1
The following changes since commit cda4a338c4243fa3bff4498b935340ac7121cc76:
1
The following changes since commit 03a3a62fbd0aa5227e978eef3c67d3978aec9e5f:
2
2
3
tcg/tci: Add TCG_TARGET_DEFAULT_MO (2017-09-07 18:57:34 +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 861d51e62bb197b43606f888dbefbabebaf0d854:
9
for you to fetch changes up to 049cfda145e96b2605cdf9739f1bcf9ebf3a83e1:
10
10
11
colo-compare: Update the COLO document to add the IOThread configuration (2017-09-08 09:34:40 +0800)
11
ebpf: Updated eBPF program and skeleton. (2023-09-08 14:33:46 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
----------------------------------------------------------------
15
----------------------------------------------------------------
16
Kamil Rytarowski (1):
16
Andrew Melnychenko (7):
17
e1000: Rename the SEC symbol to SEQEC
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.
18
24
19
Mao Zhongyi (8):
25
Ilya Maximets (1):
20
net/rocker: Remove the dead error handling
26
net: add initial support for AF_XDP network backend
21
net/rocker: Plug memory leak in pci_rocker_init()
22
net/rocker: Convert to realize()
23
net/rocker: Fix the unusual macro name
24
net/socket: Don't treat odd socket type as SOCK_STREAM
25
net/socket: Convert several helper functions to Error
26
net/net: Convert parse_host_port() to Error
27
net/socket: Improve -net socket error reporting
28
27
29
Matt Parker (1):
28
Tomasz Dzieciol (7):
30
net: rtl8139: do not use old_mmio accesses
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
31
36
32
Wang Yong (3):
37
Yuri Benditovich (2):
33
qemu-iothread: IOThread supports the GMainContext event loop
38
tap: Add check for USO features
34
colo-compare: Use IOThread to Check old packet regularly and Process pactkets of the primary
39
virtio-net: Add support for USO features
35
colo-compare: Update the COLO document to add the IOThread configuration
36
40
37
Zhang Chen (5):
41
MAINTAINERS | 4 +
38
net/filter-rewriter.c: Fix rewirter checksum bug when use virtio-net
42
ebpf/ebpf.c | 70 ++
39
MAINTAINERS: Update mail address for COLO Proxy
43
ebpf/ebpf.h | 31 +
40
net/colo-compare.c: Optimize unpredictable tcp options comparison
44
ebpf/ebpf_rss-stub.c | 6 +
41
net/colo-compare.c: Adjust net queue pop order for performance
45
ebpf/ebpf_rss.c | 150 ++-
42
net/colo-compare.c: Fix comments and scheme
46
ebpf/ebpf_rss.h | 10 +
43
47
ebpf/meson.build | 2 +-
44
MAINTAINERS | 2 +-
48
ebpf/rss.bpf.skeleton.h | 1460 ++++++++++++-----------
45
docs/colo-proxy.txt | 3 +-
49
hmp-commands.hx | 3 +
46
hw/net/e1000.c | 4 +-
50
hw/core/machine.c | 4 +
47
hw/net/e1000_regs.h | 2 +-
51
hw/net/e1000e_core.c | 80 +-
48
hw/net/e1000e_core.c | 2 +-
52
hw/net/igb_core.c | 732 ++++++++----
49
hw/net/e1000x_common.h | 2 +-
53
hw/net/igb_regs.h | 20 +-
50
hw/net/rocker/rocker.c | 94 ++++++----------------
54
hw/net/trace-events | 6 +-
51
hw/net/rocker/rocker_desc.c | 10 ---
55
hw/net/vhost_net.c | 3 +
52
hw/net/rocker/rocker_fp.c | 4 -
56
hw/net/virtio-net.c | 90 +-
53
hw/net/rocker/rocker_of_dpa.c | 20 -----
57
hw/net/vmxnet3.c | 2 +
54
hw/net/rocker/rocker_world.c | 12 ++-
58
include/hw/virtio/virtio-net.h | 1 +
55
hw/net/rtl8139.c | 53 +-----------
59
include/net/net.h | 7 +-
56
include/qemu/sockets.h | 3 +-
60
meson.build | 19 +-
57
include/sysemu/iothread.h | 4 +
61
meson_options.txt | 2 +
58
iothread.c | 45 +++++++++++
62
net/af-xdp.c | 526 ++++++++
59
net/colo-compare.c | 183 ++++++++++++++++++++++++------------------
63
net/clients.h | 5 +
60
net/filter-rewriter.c | 6 +-
64
net/meson.build | 3 +
61
net/net.c | 22 +++--
65
net/net.c | 19 +-
62
net/socket.c | 156 +++++++++++++++++++----------------
66
net/tap-bsd.c | 7 +-
63
19 files changed, 304 insertions(+), 323 deletions(-)
67
net/tap-linux.c | 27 +-
64
68
net/tap-linux.h | 2 +
65
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: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
When -net socket fails, it first reports a specific error, then
3
Passing additional parameters (USOv4 and USOv6 offloads) when
4
a generic one, like this:
4
setting TAP offloads
5
5
6
$ ./x86_64-softmmu/qemu-system-x86_64 -net socket,mcast=230.0.0.1:1234,listen
6
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: exactly one of listen=, connect=, mcast= or udp= is required
7
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
8
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: Device 'socket' could not be initialized
9
10
Convert net_socket_*_init() to Error to get rid of the superfluous second
11
error message. After the patch, the effect like this:
12
13
$ ./x86_64-softmmu/qemu-system-x86_64 -net socket,mcast=230.0.0.1:1234,listen
14
qemu-system-x86_64: -net socket,mcast=230.0.0.1:1234,listen: exactly one of listen=, connect=, mcast= or udp= is requireda
15
16
This also fixes a few silent failures to report an error.
17
18
Cc: jasowang@redhat.com
19
Cc: armbru@redhat.com
20
Cc: berrange@redhat.com
21
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
22
Reviewed-by: Markus Armbruster <armbru@redhat.com>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
---
9
---
25
net/socket.c | 92 +++++++++++++++++++++++++++++-------------------------------
10
hw/net/e1000e_core.c | 2 +-
26
1 file changed, 44 insertions(+), 48 deletions(-)
11
hw/net/igb_core.c | 2 +-
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(-)
27
25
28
diff --git a/net/socket.c b/net/socket.c
26
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
29
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
30
--- a/net/socket.c
28
--- a/hw/net/e1000e_core.c
31
+++ b/net/socket.c
29
+++ b/hw/net/e1000e_core.c
32
@@ -XXX,XX +XXX,XX @@ static void net_socket_accept(void *opaque)
30
@@ -XXX,XX +XXX,XX @@ e1000e_update_rx_offloads(E1000ECore *core)
33
static int net_socket_listen_init(NetClientState *peer,
31
34
const char *model,
32
if (core->has_vnet) {
35
const char *name,
33
qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
36
- const char *host_str)
34
- cso_state, 0, 0, 0, 0);
37
+ const char *host_str,
35
+ cso_state, 0, 0, 0, 0, 0, 0);
38
+ Error **errp)
36
}
39
{
37
}
40
NetClientState *nc;
38
41
NetSocketState *s;
39
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
42
struct sockaddr_in saddr;
40
index XXXXXXX..XXXXXXX 100644
43
int fd, ret;
41
--- a/hw/net/igb_core.c
44
- Error *err = NULL;
42
+++ b/hw/net/igb_core.c
45
43
@@ -XXX,XX +XXX,XX @@ igb_update_rx_offloads(IGBCore *core)
46
- if (parse_host_port(&saddr, host_str, &err) < 0) {
44
47
- error_report_err(err);
45
if (core->has_vnet) {
48
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
46
qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
49
return -1;
47
- cso_state, 0, 0, 0, 0);
50
}
48
+ cso_state, 0, 0, 0, 0, 0, 0);
51
49
}
52
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
50
}
53
if (fd < 0) {
51
54
- perror("socket");
52
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
55
+ error_setg_errno(errp, errno, "can't create stream socket");
53
index XXXXXXX..XXXXXXX 100644
56
return -1;
54
--- a/hw/net/virtio-net.c
57
}
55
+++ b/hw/net/virtio-net.c
58
qemu_set_nonblock(fd);
56
@@ -XXX,XX +XXX,XX @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
59
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
57
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
60
58
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
61
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
59
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
62
if (ret < 0) {
60
- !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
63
- perror("bind");
61
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)),
64
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
62
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO4)),
65
+ inet_ntoa(saddr.sin_addr));
63
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6)));
66
closesocket(fd);
64
}
67
return -1;
65
68
}
66
static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
69
ret = listen(fd, 0);
67
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
70
if (ret < 0) {
68
index XXXXXXX..XXXXXXX 100644
71
- perror("listen");
69
--- a/hw/net/vmxnet3.c
72
+ error_setg_errno(errp, errno, "can't listen on socket");
70
+++ b/hw/net/vmxnet3.c
73
closesocket(fd);
71
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_update_features(VMXNET3State *s)
74
return -1;
72
s->lro_supported,
75
}
73
s->lro_supported,
76
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
74
0,
77
static int net_socket_connect_init(NetClientState *peer,
75
+ 0,
78
const char *model,
76
+ 0,
79
const char *name,
77
0);
80
- const char *host_str)
78
}
81
+ const char *host_str,
79
}
82
+ Error **errp)
80
diff --git a/include/net/net.h b/include/net/net.h
83
{
81
index XXXXXXX..XXXXXXX 100644
84
NetSocketState *s;
82
--- a/include/net/net.h
85
int fd, connected, ret;
83
+++ b/include/net/net.h
86
struct sockaddr_in saddr;
84
@@ -XXX,XX +XXX,XX @@ typedef bool (HasVnetHdr)(NetClientState *);
87
- Error *err = NULL;
85
typedef bool (HasVnetHdrLen)(NetClientState *, int);
88
86
typedef bool (GetUsingVnetHdr)(NetClientState *);
89
- if (parse_host_port(&saddr, host_str, &err) < 0) {
87
typedef void (UsingVnetHdr)(NetClientState *, bool);
90
- error_report_err(err);
88
-typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
91
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
89
+typedef void (SetOffload)(NetClientState *, int, int, int, int, int, int, int);
92
return -1;
90
typedef int (GetVnetHdrLen)(NetClientState *);
93
}
91
typedef void (SetVnetHdrLen)(NetClientState *, int);
94
92
typedef int (SetVnetLE)(NetClientState *, bool);
95
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
93
@@ -XXX,XX +XXX,XX @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
96
if (fd < 0) {
94
bool qemu_get_using_vnet_hdr(NetClientState *nc);
97
- perror("socket");
95
void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
98
+ error_setg_errno(errp, errno, "can't create stream socket");
96
void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
99
return -1;
97
- int ecn, int ufo);
100
}
98
+ int ecn, int ufo, int uso4, int uso6);
101
qemu_set_nonblock(fd);
99
int qemu_get_vnet_hdr_len(NetClientState *nc);
102
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
100
void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
103
errno == EINVAL) {
101
int qemu_set_vnet_le(NetClientState *nc, bool is_le);
104
break;
102
diff --git a/net/net.c b/net/net.c
105
} else {
103
index XXXXXXX..XXXXXXX 100644
106
- perror("connect");
104
--- a/net/net.c
107
+ error_setg_errno(errp, errno, "can't connect socket");
105
+++ b/net/net.c
108
closesocket(fd);
106
@@ -XXX,XX +XXX,XX @@ void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
109
return -1;
107
}
110
}
108
111
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
109
void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
112
break;
110
- int ecn, int ufo)
111
+ int ecn, int ufo, int uso4, int uso6)
112
{
113
if (!nc || !nc->info->set_offload) {
114
return;
115
}
116
117
- nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
118
+ nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo, uso4, uso6);
119
}
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
+ }
113
}
170
}
114
}
171
}
115
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL, &err);
172
}
116
+ s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp);
173
diff --git a/net/tap-linux.h b/net/tap-linux.h
117
if (!s) {
174
index XXXXXXX..XXXXXXX 100644
118
- error_report_err(err);
175
--- a/net/tap-linux.h
119
return -1;
176
+++ b/net/tap-linux.h
120
}
177
@@ -XXX,XX +XXX,XX @@
121
178
#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
122
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
179
#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
123
const char *model,
180
#define TUN_F_UFO 0x10 /* I can handle UFO packets */
124
const char *name,
181
+#define TUN_F_USO4 0x20 /* I can handle USO for IPv4 packets */
125
const char *host_str,
182
+#define TUN_F_USO6 0x40 /* I can handle USO for IPv6 packets */
126
- const char *localaddr_str)
183
127
+ const char *localaddr_str,
184
#endif /* QEMU_TAP_LINUX_H */
128
+ Error **errp)
185
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
129
{
186
index XXXXXXX..XXXXXXX 100644
130
NetSocketState *s;
187
--- a/net/tap-solaris.c
131
int fd;
188
+++ b/net/tap-solaris.c
132
struct sockaddr_in saddr;
189
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
133
struct in_addr localaddr, *param_localaddr;
190
}
134
- Error *err = NULL;
191
135
192
void tap_fd_set_offload(int fd, int csum, int tso4,
136
- if (parse_host_port(&saddr, host_str, &err) < 0) {
193
- int tso6, int ecn, int ufo)
137
- error_report_err(err);
194
+ int tso6, int ecn, int ufo, int uso4, int uso6)
138
+ if (parse_host_port(&saddr, host_str, errp) < 0) {
195
{
139
return -1;
196
}
140
}
197
141
198
diff --git a/net/tap-stub.c b/net/tap-stub.c
142
if (localaddr_str != NULL) {
199
index XXXXXXX..XXXXXXX 100644
143
- if (inet_aton(localaddr_str, &localaddr) == 0)
200
--- a/net/tap-stub.c
144
+ if (inet_aton(localaddr_str, &localaddr) == 0) {
201
+++ b/net/tap-stub.c
145
+ error_setg(errp, "localaddr '%s' is not a valid IPv4 address",
202
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
146
+ localaddr_str);
203
}
147
return -1;
204
148
+ }
205
void tap_fd_set_offload(int fd, int csum, int tso4,
149
param_localaddr = &localaddr;
206
- int tso6, int ecn, int ufo)
150
} else {
207
+ int tso6, int ecn, int ufo, int uso4, int uso6)
151
param_localaddr = NULL;
208
{
152
}
209
}
153
210
154
- fd = net_socket_mcast_create(&saddr, param_localaddr, &err);
211
diff --git a/net/tap-win32.c b/net/tap-win32.c
155
+ fd = net_socket_mcast_create(&saddr, param_localaddr, errp);
212
index XXXXXXX..XXXXXXX 100644
156
if (fd < 0) {
213
--- a/net/tap-win32.c
157
- error_report_err(err);
214
+++ b/net/tap-win32.c
158
return -1;
215
@@ -XXX,XX +XXX,XX @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
159
}
216
}
160
217
161
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
218
static void tap_set_offload(NetClientState *nc, int csum, int tso4,
162
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
219
- int tso6, int ecn, int ufo)
163
if (!s) {
220
+ int tso6, int ecn, int ufo, int uso4, int uso6)
164
- error_report_err(err);
221
{
165
return -1;
222
}
166
}
223
167
224
diff --git a/net/tap.c b/net/tap.c
168
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
225
index XXXXXXX..XXXXXXX 100644
169
const char *model,
226
--- a/net/tap.c
170
const char *name,
227
+++ b/net/tap.c
171
const char *rhost,
228
@@ -XXX,XX +XXX,XX @@ static int tap_set_vnet_be(NetClientState *nc, bool is_be)
172
- const char *lhost)
229
}
173
+ const char *lhost,
230
174
+ Error **errp)
231
static void tap_set_offload(NetClientState *nc, int csum, int tso4,
175
{
232
- int tso6, int ecn, int ufo)
176
NetSocketState *s;
233
+ int tso6, int ecn, int ufo, int uso4, int uso6)
177
int fd, ret;
234
{
178
struct sockaddr_in laddr, raddr;
235
TAPState *s = DO_UPCAST(TAPState, nc, nc);
179
- Error *err = NULL;
236
if (s->fd < 0) {
180
237
return;
181
- if (parse_host_port(&laddr, lhost, &err) < 0) {
238
}
182
- error_report_err(err);
239
183
+ if (parse_host_port(&laddr, lhost, errp) < 0) {
240
- tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
184
return -1;
241
+ tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
185
}
242
}
186
243
187
- if (parse_host_port(&raddr, rhost, &err) < 0) {
244
static void tap_exit_notify(Notifier *notifier, void *data)
188
- error_report_err(err);
245
@@ -XXX,XX +XXX,XX @@ static TAPState *net_tap_fd_init(NetClientState *peer,
189
+ if (parse_host_port(&raddr, rhost, errp) < 0) {
246
s->using_vnet_hdr = false;
190
return -1;
247
s->has_ufo = tap_probe_has_ufo(s->fd);
191
}
248
s->enabled = true;
192
249
- tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
193
fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
250
+ tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
194
if (fd < 0) {
251
/*
195
- perror("socket(PF_INET, SOCK_DGRAM)");
252
* Make sure host header length is set correctly in tap:
196
+ error_setg_errno(errp, errno, "can't create datagram socket");
253
* it might have been modified by another instance of qemu.
197
return -1;
254
diff --git a/net/tap_int.h b/net/tap_int.h
198
}
255
index XXXXXXX..XXXXXXX 100644
199
256
--- a/net/tap_int.h
200
ret = socket_set_fast_reuse(fd);
257
+++ b/net/tap_int.h
201
if (ret < 0) {
258
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
202
+ error_setg_errno(errp, errno,
259
int tap_probe_vnet_hdr(int fd, Error **errp);
203
+ "can't set socket option SO_REUSEADDR");
260
int tap_probe_vnet_hdr_len(int fd, int len);
204
closesocket(fd);
261
int tap_probe_has_ufo(int fd);
205
return -1;
262
-void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo);
206
}
263
+void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
207
ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
264
+ int uso4, int uso6);
208
if (ret < 0) {
265
void tap_fd_set_vnet_hdr_len(int fd, int len);
209
- perror("bind");
266
int tap_fd_set_vnet_le(int fd, int vnet_is_le);
210
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
267
int tap_fd_set_vnet_be(int fd, int vnet_is_be);
211
+ inet_ntoa(laddr.sin_addr));
212
closesocket(fd);
213
return -1;
214
}
215
qemu_set_nonblock(fd);
216
217
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
218
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
219
if (!s) {
220
- error_report_err(err);
221
return -1;
222
}
223
224
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
225
int net_init_socket(const Netdev *netdev, const char *name,
226
NetClientState *peer, Error **errp)
227
{
228
- /* FIXME error_setg(errp, ...) on failure */
229
- Error *err = NULL;
230
const NetdevSocketOptions *sock;
231
232
assert(netdev->type == NET_CLIENT_DRIVER_SOCKET);
233
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
234
235
if (sock->has_listen + sock->has_connect + sock->has_mcast +
236
sock->has_udp > 1) {
237
- error_report("exactly one of listen=, connect=, mcast= or udp="
238
- " is required");
239
+ error_setg(errp, "exactly one of listen=, connect=, mcast= or udp="
240
+ " is required");
241
return -1;
242
}
243
244
if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) {
245
- error_report("localaddr= is only valid with mcast= or udp=");
246
+ error_setg(errp, "localaddr= is only valid with mcast= or udp=");
247
return -1;
248
}
249
250
if (sock->has_fd) {
251
int fd;
252
253
- fd = monitor_fd_param(cur_mon, sock->fd, &err);
254
+ fd = monitor_fd_param(cur_mon, sock->fd, errp);
255
if (fd == -1) {
256
- error_report_err(err);
257
return -1;
258
}
259
qemu_set_nonblock(fd);
260
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
261
}
262
263
if (sock->has_listen) {
264
- if (net_socket_listen_init(peer, "socket", name, sock->listen) == -1) {
265
+ if (net_socket_listen_init(peer, "socket", name, sock->listen, errp)
266
+ < 0) {
267
return -1;
268
}
269
return 0;
270
}
271
272
if (sock->has_connect) {
273
- if (net_socket_connect_init(peer, "socket", name, sock->connect) ==
274
- -1) {
275
+ if (net_socket_connect_init(peer, "socket", name, sock->connect, errp)
276
+ < 0) {
277
return -1;
278
}
279
return 0;
280
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
281
/* if sock->localaddr is missing, it has been initialized to "all bits
282
* zero" */
283
if (net_socket_mcast_init(peer, "socket", name, sock->mcast,
284
- sock->localaddr) == -1) {
285
+ sock->localaddr, errp) < 0) {
286
return -1;
287
}
288
return 0;
289
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
290
291
assert(sock->has_udp);
292
if (!sock->has_localaddr) {
293
- error_report("localaddr= is mandatory with udp=");
294
+ error_setg(errp, "localaddr= is mandatory with udp=");
295
return -1;
296
}
297
- if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr) ==
298
- -1) {
299
+ if (net_socket_udp_init(peer, "socket", name, sock->udp, sock->localaddr,
300
+ errp) < 0) {
301
return -1;
302
}
303
return 0;
304
--
268
--
305
2.7.4
269
2.7.4
306
307
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
2
2
3
Cc: berrange@redhat.com
3
Tap indicates support for USO features according to
4
Cc: kraxel@redhat.com
4
capabilities of current kernel module.
5
Cc: pbonzini@redhat.com
5
6
Cc: jasowang@redhat.com
6
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
Cc: armbru@redhat.com
7
Signed-off-by: Andrew Melnychecnko <andrew@daynix.com>
8
Cc: eblake@redhat.com
9
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
10
Reviewed-by: Markus Armbruster <armbru@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
9
---
13
include/qemu/sockets.h | 3 ++-
10
include/net/net.h | 3 +++
14
net/net.c | 22 +++++++++++++++++-----
11
net/net.c | 9 +++++++++
15
net/socket.c | 22 +++++++++++++++-------
12
net/tap-bsd.c | 5 +++++
16
3 files changed, 34 insertions(+), 13 deletions(-)
13
net/tap-linux.c | 12 ++++++++++++
14
net/tap-solaris.c | 5 +++++
15
net/tap-stub.c | 5 +++++
16
net/tap.c | 12 ++++++++++++
17
net/tap_int.h | 1 +
18
8 files changed, 52 insertions(+)
17
19
18
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
20
diff --git a/include/net/net.h b/include/net/net.h
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/include/qemu/sockets.h
22
--- a/include/net/net.h
21
+++ b/include/qemu/sockets.h
23
+++ b/include/net/net.h
22
@@ -XXX,XX +XXX,XX @@ void socket_listen_cleanup(int fd, Error **errp);
24
@@ -XXX,XX +XXX,XX @@ typedef void (LinkStatusChanged)(NetClientState *);
23
int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
25
typedef void (NetClientDestructor)(NetClientState *);
24
26
typedef RxFilterInfo *(QueryRxFilter)(NetClientState *);
25
/* Old, ipv4 only bits. Don't use for new code. */
27
typedef bool (HasUfo)(NetClientState *);
26
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
28
+typedef bool (HasUso)(NetClientState *);
27
+int parse_host_port(struct sockaddr_in *saddr, const char *str,
29
typedef bool (HasVnetHdr)(NetClientState *);
28
+ Error **errp);
30
typedef bool (HasVnetHdrLen)(NetClientState *, int);
29
int socket_init(void);
31
typedef bool (GetUsingVnetHdr)(NetClientState *);
30
32
@@ -XXX,XX +XXX,XX @@ typedef struct NetClientInfo {
31
/**
33
QueryRxFilter *query_rx_filter;
34
NetPoll *poll;
35
HasUfo *has_ufo;
36
+ HasUso *has_uso;
37
HasVnetHdr *has_vnet_hdr;
38
HasVnetHdrLen *has_vnet_hdr_len;
39
GetUsingVnetHdr *get_using_vnet_hdr;
40
@@ -XXX,XX +XXX,XX @@ void qemu_set_info_str(NetClientState *nc,
41
const char *fmt, ...) G_GNUC_PRINTF(2, 3);
42
void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
43
bool qemu_has_ufo(NetClientState *nc);
44
+bool qemu_has_uso(NetClientState *nc);
45
bool qemu_has_vnet_hdr(NetClientState *nc);
46
bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
47
bool qemu_get_using_vnet_hdr(NetClientState *nc);
32
diff --git a/net/net.c b/net/net.c
48
diff --git a/net/net.c b/net/net.c
33
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
34
--- a/net/net.c
50
--- a/net/net.c
35
+++ b/net/net.c
51
+++ b/net/net.c
36
@@ -XXX,XX +XXX,XX @@ static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
52
@@ -XXX,XX +XXX,XX @@ bool qemu_has_ufo(NetClientState *nc)
53
return nc->info->has_ufo(nc);
54
}
55
56
+bool qemu_has_uso(NetClientState *nc)
57
+{
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)
66
{
67
if (!nc || !nc->info->has_vnet_hdr) {
68
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/net/tap-bsd.c
71
+++ b/net/tap-bsd.c
72
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
37
return 0;
73
return 0;
38
}
74
}
39
75
40
-int parse_host_port(struct sockaddr_in *saddr, const char *str)
76
+int tap_probe_has_uso(int fd)
41
+int parse_host_port(struct sockaddr_in *saddr, const char *str,
77
+{
42
+ Error **errp)
78
+ return 0;
79
+}
80
+
81
int tap_probe_vnet_hdr_len(int fd, int len)
43
{
82
{
44
char buf[512];
83
return 0;
45
struct hostent *he;
84
diff --git a/net/tap-linux.c b/net/tap-linux.c
46
@@ -XXX,XX +XXX,XX @@ int parse_host_port(struct sockaddr_in *saddr, const char *str)
85
index XXXXXXX..XXXXXXX 100644
47
int port;
86
--- a/net/tap-linux.c
48
87
+++ b/net/tap-linux.c
49
p = str;
88
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
50
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
89
return 1;
51
+ if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
90
}
52
+ error_setg(errp, "host address '%s' doesn't contain ':' "
91
53
+ "separating host from port", str);
92
+int tap_probe_has_uso(int fd)
54
return -1;
93
+{
94
+ unsigned offload;
95
+
96
+ offload = TUN_F_CSUM | TUN_F_USO4 | TUN_F_USO6;
97
+
98
+ if (ioctl(fd, TUNSETOFFLOAD, offload) < 0) {
99
+ return 0;
55
+ }
100
+ }
56
saddr->sin_family = AF_INET;
101
+ return 1;
57
if (buf[0] == '\0') {
102
+}
58
saddr->sin_addr.s_addr = 0;
103
+
59
} else {
104
/* Verify that we can assign given length */
60
if (qemu_isdigit(buf[0])) {
105
int tap_probe_vnet_hdr_len(int fd, int len)
61
- if (!inet_aton(buf, &saddr->sin_addr))
106
{
62
+ if (!inet_aton(buf, &saddr->sin_addr)) {
107
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
63
+ error_setg(errp, "host address '%s' is not a valid "
108
index XXXXXXX..XXXXXXX 100644
64
+ "IPv4 address", buf);
109
--- a/net/tap-solaris.c
65
return -1;
110
+++ b/net/tap-solaris.c
66
+ }
111
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
67
} else {
68
- if ((he = gethostbyname(buf)) == NULL)
69
+ he = gethostbyname(buf);
70
+ if (he == NULL) {
71
+ error_setg(errp, "can't resolve host address '%s'", buf);
72
return - 1;
73
+ }
74
saddr->sin_addr = *(struct in_addr *)he->h_addr;
75
}
76
}
77
port = strtol(p, (char **)&r, 0);
78
- if (r == p)
79
+ if (r == p) {
80
+ error_setg(errp, "port number '%s' is invalid", p);
81
return -1;
82
+ }
83
saddr->sin_port = htons(port);
84
return 0;
112
return 0;
85
}
113
}
86
diff --git a/net/socket.c b/net/socket.c
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
87
index XXXXXXX..XXXXXXX 100644
124
index XXXXXXX..XXXXXXX 100644
88
--- a/net/socket.c
125
--- a/net/tap-stub.c
89
+++ b/net/socket.c
126
+++ b/net/tap-stub.c
90
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
127
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
91
*/
128
return 0;
92
129
}
93
if (is_connected && mcast != NULL) {
130
94
- if (parse_host_port(&saddr, mcast) < 0) {
131
+int tap_probe_has_uso(int fd)
95
- error_setg(errp, "fd=%d failed parse_host_port()", fd);
132
+{
96
+ if (parse_host_port(&saddr, mcast, errp) < 0) {
133
+ return 0;
97
goto err;
134
+}
98
}
135
+
99
/* must be bound */
136
int tap_probe_vnet_hdr_len(int fd, int len)
100
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
137
{
101
NetSocketState *s;
138
return 0;
102
struct sockaddr_in saddr;
139
diff --git a/net/tap.c b/net/tap.c
103
int fd, ret;
140
index XXXXXXX..XXXXXXX 100644
104
+ Error *err = NULL;
141
--- a/net/tap.c
105
142
+++ b/net/tap.c
106
- if (parse_host_port(&saddr, host_str) < 0)
143
@@ -XXX,XX +XXX,XX @@ typedef struct TAPState {
107
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
144
bool write_poll;
108
+ error_report_err(err);
145
bool using_vnet_hdr;
109
return -1;
146
bool has_ufo;
110
+ }
147
+ bool has_uso;
111
148
bool enabled;
112
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
149
VHostNetState *vhost_net;
113
if (fd < 0) {
150
unsigned host_vnet_hdr_len;
114
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
151
@@ -XXX,XX +XXX,XX @@ static bool tap_has_ufo(NetClientState *nc)
115
struct sockaddr_in saddr;
152
return s->has_ufo;
116
Error *err = NULL;
153
}
117
154
118
- if (parse_host_port(&saddr, host_str) < 0)
155
+static bool tap_has_uso(NetClientState *nc)
119
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
156
+{
120
+ error_report_err(err);
157
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
121
return -1;
158
+
122
+ }
159
+ assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
123
160
+
124
fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
161
+ return s->has_uso;
125
if (fd < 0) {
162
+}
126
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
163
+
127
struct in_addr localaddr, *param_localaddr;
164
static bool tap_has_vnet_hdr(NetClientState *nc)
128
Error *err = NULL;
165
{
129
166
TAPState *s = DO_UPCAST(TAPState, nc, nc);
130
- if (parse_host_port(&saddr, host_str) < 0)
167
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_tap_info = {
131
+ if (parse_host_port(&saddr, host_str, &err) < 0) {
168
.poll = tap_poll,
132
+ error_report_err(err);
169
.cleanup = tap_cleanup,
133
return -1;
170
.has_ufo = tap_has_ufo,
134
+ }
171
+ .has_uso = tap_has_uso,
135
172
.has_vnet_hdr = tap_has_vnet_hdr,
136
if (localaddr_str != NULL) {
173
.has_vnet_hdr_len = tap_has_vnet_hdr_len,
137
if (inet_aton(localaddr_str, &localaddr) == 0)
174
.get_using_vnet_hdr = tap_get_using_vnet_hdr,
138
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
175
@@ -XXX,XX +XXX,XX @@ static TAPState *net_tap_fd_init(NetClientState *peer,
139
struct sockaddr_in laddr, raddr;
176
s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
140
Error *err = NULL;
177
s->using_vnet_hdr = false;
141
178
s->has_ufo = tap_probe_has_ufo(s->fd);
142
- if (parse_host_port(&laddr, lhost) < 0) {
179
+ s->has_uso = tap_probe_has_uso(s->fd);
143
+ if (parse_host_port(&laddr, lhost, &err) < 0) {
180
s->enabled = true;
144
+ error_report_err(err);
181
tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
145
return -1;
182
/*
146
}
183
diff --git a/net/tap_int.h b/net/tap_int.h
147
184
index XXXXXXX..XXXXXXX 100644
148
- if (parse_host_port(&raddr, rhost) < 0) {
185
--- a/net/tap_int.h
149
+ if (parse_host_port(&raddr, rhost, &err) < 0) {
186
+++ b/net/tap_int.h
150
+ error_report_err(err);
187
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
151
return -1;
188
int tap_probe_vnet_hdr(int fd, Error **errp);
152
}
189
int tap_probe_vnet_hdr_len(int fd, int len);
153
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);
154
--
195
--
155
2.7.4
196
2.7.4
156
157
diff view generated by jsdifflib
1
From: Wang Yong <wang.yong155@zte.com.cn>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
Update colo-proxy.txt,add IOThread configuration.
3
New features are subject to check with vhost-user and vdpa.
4
Later we have to configure IOThread,if not COLO can not work.
5
4
6
Reviewed-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
6
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
8
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
8
---
11
docs/colo-proxy.txt | 3 ++-
9
hw/net/vhost_net.c | 3 +++
12
1 file changed, 2 insertions(+), 1 deletion(-)
10
net/vhost-vdpa.c | 3 +++
11
2 files changed, 6 insertions(+)
13
12
14
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
13
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/colo-proxy.txt
15
--- a/hw/net/vhost_net.c
17
+++ b/docs/colo-proxy.txt
16
+++ b/hw/net/vhost_net.c
18
@@ -XXX,XX +XXX,XX @@ Primary(ip:3.3.3.3):
17
@@ -XXX,XX +XXX,XX @@ static const int user_feature_bits[] = {
19
-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
18
VIRTIO_F_RING_RESET,
20
-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
19
VIRTIO_NET_F_RSS,
21
-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
20
VIRTIO_NET_F_HASH_REPORT,
22
+-object iothread,id=iothread1
21
+ VIRTIO_NET_F_GUEST_USO4,
23
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
22
+ VIRTIO_NET_F_GUEST_USO6,
24
-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
23
+ VIRTIO_NET_F_HOST_USO,
25
-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
24
26
--object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0
25
/* This bit implies RARP isn't sent by QEMU out of band */
27
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,iothread=iothread1
26
VIRTIO_NET_F_GUEST_ANNOUNCE,
28
27
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
29
Secondary(ip:3.3.3.8):
28
index XXXXXXX..XXXXXXX 100644
30
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
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,
31
--
46
--
32
2.7.4
47
2.7.4
33
34
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
2
2
3
Cc: jasowang@redhat.com
3
USO features of virtio-net device depend on kernel ability
4
Cc: jiri@resnulli.us
4
to support them, for backward compatibility by default the
5
Cc: armbru@redhat.com
5
features are disabled on 8.0 and earlier.
6
Cc: f4bug@amsat.org
6
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
8
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
8
Signed-off-by: Andrew Melnychecnko <andrew@daynix.com>
9
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
10
---
13
hw/net/rocker/rocker.c | 18 +++++++++---------
11
hw/core/machine.c | 4 ++++
14
1 file changed, 9 insertions(+), 9 deletions(-)
12
hw/net/virtio-net.c | 31 +++++++++++++++++++++++++++++--
13
2 files changed, 33 insertions(+), 2 deletions(-)
15
14
16
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
15
diff --git a/hw/core/machine.c b/hw/core/machine.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/rocker/rocker.c
17
--- a/hw/core/machine.c
19
+++ b/hw/net/rocker/rocker.c
18
+++ b/hw/core/machine.c
20
@@ -XXX,XX +XXX,XX @@ struct rocker {
19
@@ -XXX,XX +XXX,XX @@
21
QLIST_ENTRY(rocker) next;
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"},
22
};
34
};
23
35
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
24
-#define ROCKER "rocker"
36
25
+#define TYPE_ROCKER "rocker"
37
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
26
38
index XXXXXXX..XXXXXXX 100644
27
-#define to_rocker(obj) \
39
--- a/hw/net/virtio-net.c
28
- OBJECT_CHECK(Rocker, (obj), ROCKER)
40
+++ b/hw/net/virtio-net.c
29
+#define ROCKER(obj) \
41
@@ -XXX,XX +XXX,XX @@ static int peer_has_ufo(VirtIONet *n)
30
+ OBJECT_CHECK(Rocker, (obj), TYPE_ROCKER)
42
return n->has_ufo;
31
43
}
32
static QLIST_HEAD(, rocker) rockers;
44
33
45
+static int peer_has_uso(VirtIONet *n)
34
@@ -XXX,XX +XXX,XX @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
46
+{
35
47
+ if (!peer_has_vnet_hdr(n)) {
36
static void pci_rocker_realize(PCIDevice *dev, Error **errp)
48
+ return 0;
49
+ }
50
+
51
+ return qemu_has_uso(qemu_get_queue(n->nic)->peer);
52
+}
53
+
54
static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
55
int version_1, int hash_report)
37
{
56
{
38
- Rocker *r = to_rocker(dev);
57
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
39
+ Rocker *r = ROCKER(dev);
58
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
40
const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
59
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
41
const MACAddr dflt = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } };
60
42
static int sw_index;
61
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
43
@@ -XXX,XX +XXX,XX @@ static void pci_rocker_realize(PCIDevice *dev, Error **errp)
62
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
44
/* validate switch properties */
63
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
45
64
+
46
if (!r->name) {
65
virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
47
- r->name = g_strdup(ROCKER);
48
+ r->name = g_strdup(TYPE_ROCKER);
49
}
66
}
50
67
51
if (rocker_find(r->name)) {
68
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
52
@@ -XXX,XX +XXX,XX @@ err_world_type_by_name:
69
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
53
70
}
54
static void pci_rocker_uninit(PCIDevice *dev)
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)
55
{
87
{
56
- Rocker *r = to_rocker(dev);
88
static const uint64_t guest_offloads_mask =
57
+ Rocker *r = ROCKER(dev);
89
(1ULL << VIRTIO_NET_F_GUEST_CSUM) |
58
int i;
90
(1ULL << VIRTIO_NET_F_GUEST_TSO4) |
59
91
(1ULL << VIRTIO_NET_F_GUEST_TSO6) |
60
QLIST_REMOVE(r, next);
92
(1ULL << VIRTIO_NET_F_GUEST_ECN) |
61
@@ -XXX,XX +XXX,XX @@ static void pci_rocker_uninit(PCIDevice *dev)
93
- (1ULL << VIRTIO_NET_F_GUEST_UFO);
62
94
+ (1ULL << VIRTIO_NET_F_GUEST_UFO) |
63
static void rocker_reset(DeviceState *dev)
95
+ (1ULL << VIRTIO_NET_F_GUEST_USO4) |
64
{
96
+ (1ULL << VIRTIO_NET_F_GUEST_USO6);
65
- Rocker *r = to_rocker(dev);
97
66
+ Rocker *r = ROCKER(dev);
98
return guest_offloads_mask & features;
67
int i;
99
}
68
100
@@ -XXX,XX +XXX,XX @@ static Property virtio_net_properties[] = {
69
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
101
DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
70
@@ -XXX,XX +XXX,XX @@ static Property rocker_properties[] = {
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(),
71
};
111
};
72
112
73
static const VMStateDescription rocker_vmsd = {
74
- .name = ROCKER,
75
+ .name = TYPE_ROCKER,
76
.unmigratable = 1,
77
};
78
79
@@ -XXX,XX +XXX,XX @@ static void rocker_class_init(ObjectClass *klass, void *data)
80
}
81
82
static const TypeInfo rocker_info = {
83
- .name = ROCKER,
84
+ .name = TYPE_ROCKER,
85
.parent = TYPE_PCI_DEVICE,
86
.instance_size = sizeof(Rocker),
87
.class_init = rocker_class_init,
88
--
113
--
89
2.7.4
114
2.7.4
90
91
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
Because vnet_hdr have a offset to net packet, we must add it when use
3
TCP ACK detection is no longer present in igb.
4
virtio-net.
5
4
6
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
net/filter-rewriter.c | 6 ++++--
10
hw/net/igb_core.c | 5 -----
10
1 file changed, 4 insertions(+), 2 deletions(-)
11
1 file changed, 5 deletions(-)
11
12
12
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
13
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-rewriter.c
15
--- a/hw/net/igb_core.c
15
+++ b/net/filter-rewriter.c
16
+++ b/hw/net/igb_core.c
16
@@ -XXX,XX +XXX,XX @@ static int handle_primary_tcp_pkt(NetFilterState *nf,
17
@@ -XXX,XX +XXX,XX @@ igb_build_rx_metadata(IGBCore *core,
17
/* handle packets to the secondary from the primary */
18
trace_e1000e_rx_metadata_ip_id(*ip_id);
18
tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);
19
20
- net_checksum_calculate((uint8_t *)pkt->data, pkt->size);
21
+ net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
22
+ pkt->size - pkt->vnet_hdr_len);
23
}
24
}
19
}
25
20
26
@@ -XXX,XX +XXX,XX @@ static int handle_secondary_tcp_pkt(NetFilterState *nf,
21
- if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && net_rx_pkt_is_tcp_ack(pkt)) {
27
/* handle packets to the primary from the secondary*/
22
- *status_flags |= E1000_RXD_STAT_ACK;
28
tcp_pkt->th_seq = htonl(ntohl(tcp_pkt->th_seq) - conn->offset);
23
- trace_e1000e_rx_metadata_ack();
29
24
- }
30
- net_checksum_calculate((uint8_t *)pkt->data, pkt->size);
25
-
31
+ net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len,
26
if (pkt_info) {
32
+ pkt->size - pkt->vnet_hdr_len);
27
*pkt_info = rss_info->enabled ? rss_info->type : 0;
33
}
34
}
35
28
36
--
29
--
37
2.7.4
30
2.7.4
38
39
diff view generated by jsdifflib
1
From: Kamil Rytarowski <n54@gmx.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
SunOS defines SEC in <sys/time.h> as 1 (commonly used time symbols).
3
Rename E1000E_RingInfo_st and E1000E_RingInfo according to qemu typdefs guide.
4
4
5
This fixes build on SmartOS (Joyent).
5
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
6
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Patch cherry-picked from pkgsrc by jperkin (Joyent).
7
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
9
Signed-off-by: Kamil Rytarowski <n54@gmx.com>
10
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
9
---
13
hw/net/e1000.c | 4 ++--
10
hw/net/e1000e_core.c | 34 +++++++++++++++++-----------------
14
hw/net/e1000_regs.h | 2 +-
11
hw/net/igb_core.c | 42 +++++++++++++++++++++---------------------
15
hw/net/e1000e_core.c | 2 +-
12
2 files changed, 38 insertions(+), 38 deletions(-)
16
hw/net/e1000x_common.h | 2 +-
17
4 files changed, 5 insertions(+), 5 deletions(-)
18
13
19
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/e1000.c
22
+++ b/hw/net/e1000.c
23
@@ -XXX,XX +XXX,XX @@ static uint32_t (*macreg_readops[])(E1000State *, int) = {
24
getreg(TADV), getreg(ITR), getreg(FCRUC), getreg(IPAV),
25
getreg(WUC), getreg(WUS), getreg(SCC), getreg(ECOL),
26
getreg(MCC), getreg(LATECOL), getreg(COLC), getreg(DC),
27
- getreg(TNCRS), getreg(SEC), getreg(CEXTERR), getreg(RLEC),
28
+ getreg(TNCRS), getreg(SEQEC), getreg(CEXTERR), getreg(RLEC),
29
getreg(XONRXC), getreg(XONTXC), getreg(XOFFRXC), getreg(XOFFTXC),
30
getreg(RFC), getreg(RJC), getreg(RNBC), getreg(TSCTFC),
31
getreg(MGTPRC), getreg(MGTPDC), getreg(MGTPTC), getreg(GORCL),
32
@@ -XXX,XX +XXX,XX @@ static const uint8_t mac_reg_access[0x8000] = {
33
[FFLT] = markflag(MAC), [FFMT] = markflag(MAC),
34
[SCC] = markflag(MAC), [FCRUC] = markflag(MAC),
35
[LATECOL] = markflag(MAC), [COLC] = markflag(MAC),
36
- [SEC] = markflag(MAC), [CEXTERR] = markflag(MAC),
37
+ [SEQEC] = markflag(MAC), [CEXTERR] = markflag(MAC),
38
[XONTXC] = markflag(MAC), [XOFFRXC] = markflag(MAC),
39
[RJC] = markflag(MAC), [RNBC] = markflag(MAC),
40
[MGTPDC] = markflag(MAC), [MGTPTC] = markflag(MAC),
41
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/net/e1000_regs.h
44
+++ b/hw/net/e1000_regs.h
45
@@ -XXX,XX +XXX,XX @@
46
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
47
#define E1000_DC 0x04030 /* Defer Count - R/clr */
48
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
49
-#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
50
+#define E1000_SEQEC 0x04038 /* Sequence Error Count - R/clr */
51
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
52
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
53
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
54
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
55
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/e1000e_core.c
16
--- a/hw/net/e1000e_core.c
57
+++ b/hw/net/e1000e_core.c
17
+++ b/hw/net/e1000e_core.c
58
@@ -XXX,XX +XXX,XX @@ static uint32_t (*e1000e_macreg_readops[])(E1000ECore *, int) = {
18
@@ -XXX,XX +XXX,XX @@ e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t base,
59
e1000e_getreg(RDLEN0),
19
return e1000e_tx_wb_interrupt_cause(core, queue_idx);
60
e1000e_getreg(RDH1),
20
}
61
e1000e_getreg(LATECOL),
21
62
- e1000e_getreg(SEC),
22
-typedef struct E1000E_RingInfo_st {
63
+ e1000e_getreg(SEQEC),
23
+typedef struct E1000ERingInfo {
64
e1000e_getreg(XONTXC),
24
int dbah;
65
e1000e_getreg(WUS),
25
int dbal;
66
e1000e_getreg(GORCL),
26
int dlen;
67
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
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
68
index XXXXXXX..XXXXXXX 100644
157
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/net/e1000x_common.h
158
--- a/hw/net/igb_core.c
70
+++ b/hw/net/e1000x_common.h
159
+++ b/hw/net/igb_core.c
71
@@ -XXX,XX +XXX,XX @@ enum {
160
@@ -XXX,XX +XXX,XX @@ static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx)
72
defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV),
161
return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
73
defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL),
162
}
74
defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
163
75
- defreg(TNCRS), defreg(SEC), defreg(CEXTERR), defreg(RLEC),
164
-typedef struct E1000E_RingInfo_st {
76
+ defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC),
165
+typedef struct E1000ERingInfo {
77
defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
166
int dbah;
78
defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT),
167
int dbal;
79
defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
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;
80
--
336
--
81
2.7.4
337
2.7.4
82
83
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
The rocker device still implements the old PCIDeviceClass .init()
3
Refactoring is done in preparation for support of multiple advanced
4
instead of the new .realize(). All devices need to be converted to
4
descriptors RX modes, especially packet-split modes.
5
.realize().
6
5
7
.init() reports errors with fprintf() and return 0 on success, negative
6
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
8
number on failure. Meanwhile, when -device rocker fails, it first report
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
a specific error, then a generic one, like this:
8
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
11
$ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
12
rocker: name too long; please shorten to at most 9 chars
13
qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
14
15
Now, convert it to .realize() that passes errors to its callers via its
16
errp argument. Also avoid the superfluous second error message. After
17
the patch, effect like this:
18
19
$ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
20
qemu-system-x86_64: -device rocker,name=qemu-rocker: name too long; please shorten to at most 9 chars
21
22
Cc: jasowang@redhat.com
23
Cc: jiri@resnulli.us
24
Cc: armbru@redhat.com
25
Cc: f4bug@amsat.org
26
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
27
Reviewed-by: Markus Armbruster <armbru@redhat.com>
28
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
30
---
10
---
31
hw/net/rocker/rocker.c | 27 +++++++++++----------------
11
hw/net/igb_core.c | 170 +++++++++++++++++++++++++++-------------------------
32
1 file changed, 11 insertions(+), 16 deletions(-)
12
hw/net/igb_regs.h | 10 ++--
13
hw/net/trace-events | 4 +-
14
3 files changed, 96 insertions(+), 88 deletions(-)
33
15
34
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
16
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
35
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/net/rocker/rocker.c
18
--- a/hw/net/igb_core.c
37
+++ b/hw/net/rocker/rocker.c
19
+++ b/hw/net/igb_core.c
38
@@ -XXX,XX +XXX,XX @@ rollback:
20
@@ -XXX,XX +XXX,XX @@ igb_verify_csum_in_sw(IGBCore *core,
39
return err;
40
}
21
}
41
22
42
-static int rocker_msix_init(Rocker *r)
23
static void
43
+static int rocker_msix_init(Rocker *r, Error **errp)
24
-igb_build_rx_metadata(IGBCore *core,
44
{
25
- struct NetRxPkt *pkt,
45
PCIDevice *dev = PCI_DEVICE(r);
26
- bool is_eop,
46
int err;
27
- const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
47
- Error *local_err = NULL;
28
- uint16_t *pkt_info, uint16_t *hdr_info,
48
29
- uint32_t *rss,
49
err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
30
- uint32_t *status_flags,
50
&r->msix_bar,
31
- uint16_t *ip_id,
51
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
32
- uint16_t *vlan_tag)
52
&r->msix_bar,
33
+igb_build_rx_metadata_common(IGBCore *core,
53
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
34
+ struct NetRxPkt *pkt,
54
- 0, &local_err);
35
+ bool is_eop,
55
+ 0, errp);
36
+ uint32_t *status_flags,
56
if (err) {
37
+ uint16_t *vlan_tag)
57
- error_report_err(local_err);
38
{
58
return err;
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;
59
}
48
}
60
49
@@ -XXX,XX +XXX,XX @@ igb_build_rx_metadata(IGBCore *core,
61
@@ -XXX,XX +XXX,XX @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
50
trace_e1000e_rx_metadata_vlan(*vlan_tag);
62
return NULL;
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);
63
}
137
}
64
138
65
-static int pci_rocker_init(PCIDevice *dev)
139
+static uint16_t
66
+static void pci_rocker_realize(PCIDevice *dev, Error **errp)
140
+igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
67
{
141
+{
68
Rocker *r = to_rocker(dev);
142
+ uint16_t pkt_type;
69
const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
143
+ bool hasip4, hasip6;
70
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
144
+ EthL4HdrProto l4hdr_proto;
71
145
+
72
r->world_dflt = rocker_world_type_by_name(r, r->world_name);
146
+ if (etqf < 8) {
73
if (!r->world_dflt) {
147
+ pkt_type = BIT(11) | etqf;
74
- fprintf(stderr,
148
+ return pkt_type;
75
- "rocker: requested world \"%s\" does not exist\n",
149
+ }
76
+ error_setg(errp,
150
+
77
+ "invalid argument requested world %s does not exist",
151
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
78
r->world_name);
152
+
79
- err = -EINVAL;
153
+ if (hasip6 && !(core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
80
goto err_world_type_by_name;
154
+ pkt_type = E1000_ADVRXD_PKT_IP6;
81
}
155
+ } else if (hasip4) {
82
156
+ pkt_type = E1000_ADVRXD_PKT_IP4;
83
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
157
+ } else {
84
158
+ pkt_type = 0;
85
/* MSI-X init */
159
+ }
86
160
+
87
- err = rocker_msix_init(r);
161
+ switch (l4hdr_proto) {
88
+ err = rocker_msix_init(r, errp);
162
+ case ETH_L4_HDR_PROTO_TCP:
89
if (err) {
163
+ pkt_type |= E1000_ADVRXD_PKT_TCP;
90
goto err_msix_init;
164
+ break;
91
}
165
+ case ETH_L4_HDR_PROTO_UDP:
92
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
166
+ pkt_type |= E1000_ADVRXD_PKT_UDP;
93
}
167
+ break;
94
168
+ case ETH_L4_HDR_PROTO_SCTP:
95
if (rocker_find(r->name)) {
169
+ pkt_type |= E1000_ADVRXD_PKT_SCTP;
96
- err = -EEXIST;
170
+ break;
97
+ error_setg(errp, "%s already exists", r->name);
171
+ default:
98
goto err_duplicate;
172
+ break;
99
}
173
+ }
100
174
+
101
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
175
+ return pkt_type;
102
#define ROCKER_IFNAMSIZ 16
176
+}
103
#define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
177
+
104
if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
178
static inline void
105
- fprintf(stderr,
179
igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
106
- "rocker: name too long; please shorten to at most %d chars\n",
180
struct NetRxPkt *pkt,
107
+ error_setg(errp,
181
const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
108
+ "name too long; please shorten to at most %d chars",
182
uint16_t length)
109
MAX_ROCKER_NAME_LEN);
183
{
110
- err = -EINVAL;
184
+ bool hasip4, hasip6;
111
goto err_name_too_long;
185
+ EthL4HdrProto l4hdr_proto;
112
}
186
+ uint16_t rss_type = 0, pkt_type;
113
187
+ bool eop = (pkt != NULL);
114
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
188
+ uint32_t adv_desc_status_error = 0;
115
189
memset(&desc->wb, 0, sizeof(desc->wb));
116
QLIST_INSERT_HEAD(&rockers, r, next);
190
117
191
desc->wb.upper.length = cpu_to_le16(length);
118
- return 0;
192
+ igb_build_rx_metadata_common(core, pkt, eop,
119
+ return;
193
+ &desc->wb.upper.status_error,
120
194
+ &desc->wb.upper.vlan);
121
err_name_too_long:
195
+
122
err_duplicate:
196
+ if (!eop) {
123
@@ -XXX,XX +XXX,XX @@ err_world_type_by_name:
197
+ return;
124
world_free(r->worlds[i]);
198
+ }
125
}
199
+
126
}
200
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
127
- return err;
201
+
202
+ if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
203
+ if (rss_info->enabled) {
204
+ desc->wb.lower.hi_dword.rss = cpu_to_le32(rss_info->hash);
205
+ rss_type = rss_info->type;
206
+ trace_igb_rx_metadata_rss(desc->wb.lower.hi_dword.rss, rss_type);
207
+ }
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);
128
}
232
}
129
233
130
static void pci_rocker_uninit(PCIDevice *dev)
234
static inline void
131
@@ -XXX,XX +XXX,XX @@ static void rocker_class_init(ObjectClass *klass, void *data)
235
@@ -XXX,XX +XXX,XX @@ igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
132
DeviceClass *dc = DEVICE_CLASS(klass);
236
uint16_t etqf, bool ts, uint16_t length)
133
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
237
{
134
238
if (igb_rx_use_legacy_descriptor(core)) {
135
- k->init = pci_rocker_init;
239
- igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
136
+ k->realize = pci_rocker_realize;
240
- etqf, ts, length);
137
k->exit = pci_rocker_uninit;
241
+ igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
138
k->vendor_id = PCI_VENDOR_ID_REDHAT;
242
} else {
139
k->device_id = PCI_DEVICE_ID_REDHAT_ROCKER;
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
246
index XXXXXXX..XXXXXXX 100644
247
--- a/hw/net/igb_regs.h
248
+++ b/hw/net/igb_regs.h
249
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
250
251
#define E1000_STATUS_NUM_VFS_SHIFT 14
252
253
-#define E1000_ADVRXD_PKT_IP4 BIT(4)
254
-#define E1000_ADVRXD_PKT_IP6 BIT(6)
255
-#define E1000_ADVRXD_PKT_TCP BIT(8)
256
-#define E1000_ADVRXD_PKT_UDP BIT(9)
257
-#define E1000_ADVRXD_PKT_SCTP BIT(10)
258
+#define E1000_ADVRXD_PKT_IP4 BIT(0)
259
+#define E1000_ADVRXD_PKT_IP6 BIT(2)
260
+#define E1000_ADVRXD_PKT_TCP BIT(4)
261
+#define E1000_ADVRXD_PKT_UDP BIT(5)
262
+#define E1000_ADVRXD_PKT_SCTP BIT(6)
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
140
--
288
--
141
2.7.4
289
2.7.4
142
143
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
Refactoring is done in preparation for support of multiple advanced
4
descriptors RX modes, especially packet-split modes.
5
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>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
10
---
6
net/colo-compare.c | 59 ++++++++++++++++++++++++++++--------------------------
11
hw/net/e1000e_core.c | 18 ++--
7
1 file changed, 31 insertions(+), 28 deletions(-)
12
hw/net/igb_core.c | 213 ++++++++++++++++++++++++++++++-----------------
13
tests/qtest/libqos/igb.c | 5 ++
14
3 files changed, 150 insertions(+), 86 deletions(-)
8
15
9
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
10
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
11
--- a/net/colo-compare.c
18
--- a/hw/net/e1000e_core.c
12
+++ b/net/colo-compare.c
19
+++ b/hw/net/e1000e_core.c
13
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
14
#define REGULAR_PACKET_CHECK_MS 3000
21
}
15
22
16
/*
23
static void
17
- + CompareState ++
24
-e1000e_write_to_rx_buffers(E1000ECore *core,
18
- | |
25
- hwaddr ba[MAX_PS_BUFFERS],
19
- +---------------+ +---------------+ +---------------+
26
- e1000e_ba_state *bastate,
20
- |conn list +--->conn +--------->conn |
27
- const char *data,
21
- +---------------+ +---------------+ +---------------+
28
- dma_addr_t data_len)
22
- | | | | | |
29
+e1000e_write_payload_frag_to_rx_buffers(E1000ECore *core,
23
- +---------------+ +---v----+ +---v----+ +---v----+ +---v----+
30
+ hwaddr ba[MAX_PS_BUFFERS],
24
- |primary | |secondary |primary | |secondary
31
+ e1000e_ba_state *bastate,
25
- |packet | |packet + |packet | |packet +
32
+ const char *data,
26
- +--------+ +--------+ +--------+ +--------+
33
+ dma_addr_t data_len)
27
- | | | |
34
{
28
- +---v----+ +---v----+ +---v----+ +---v----+
35
while (data_len > 0) {
29
- |primary | |secondary |primary | |secondary
36
uint32_t cur_buf_len = core->rxbuf_sizes[bastate->cur_idx];
30
- |packet | |packet + |packet | |packet +
37
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
31
- +--------+ +--------+ +--------+ +--------+
38
while (copy_size) {
32
- | | | |
39
iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
33
- +---v----+ +---v----+ +---v----+ +---v----+
40
34
- |primary | |secondary |primary | |secondary
41
- e1000e_write_to_rx_buffers(core, ba, &bastate,
35
- |packet | |packet + |packet | |packet +
42
- iov->iov_base + iov_ofs, iov_copy);
36
- +--------+ +--------+ +--------+ +--------+
43
+ e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
37
-*/
44
+ iov->iov_base +
38
+ * + CompareState ++
45
+ iov_ofs,
39
+ * | |
46
+ iov_copy);
40
+ * +---------------+ +---------------+ +---------------+
47
41
+ * | conn list + - > conn + ------- > conn + -- > ......
48
copy_size -= iov_copy;
42
+ * +---------------+ +---------------+ +---------------+
49
iov_ofs += iov_copy;
43
+ * | | | | | |
50
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
44
+ * +---------------+ +---v----+ +---v----+ +---v----+ +---v----+
51
45
+ * |primary | |secondary |primary | |secondary
52
if (desc_offset + desc_size >= total_size) {
46
+ * |packet | |packet + |packet | |packet +
53
/* Simulate FCS checksum presence in the last descriptor */
47
+ * +--------+ +--------+ +--------+ +--------+
54
- e1000e_write_to_rx_buffers(core, ba, &bastate,
48
+ * | | | |
55
+ e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
49
+ * +---v----+ +---v----+ +---v----+ +---v----+
56
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
50
+ * |primary | |secondary |primary | |secondary
57
}
51
+ * |packet | |packet + |packet | |packet +
58
}
52
+ * +--------+ +--------+ +--------+ +--------+
59
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
53
+ * | | | |
60
index XXXXXXX..XXXXXXX 100644
54
+ * +---v----+ +---v----+ +---v----+ +---v----+
61
--- a/hw/net/igb_core.c
55
+ * |primary | |secondary |primary | |secondary
62
+++ b/hw/net/igb_core.c
56
+ * |packet | |packet + |packet | |packet +
63
@@ -XXX,XX +XXX,XX @@ igb_has_rxbufs(IGBCore *core, const E1000ERingInfo *r, size_t total_size)
57
+ * +--------+ +--------+ +--------+ +--------+
64
bufsize;
58
+ */
65
}
59
typedef struct CompareState {
66
60
Object parent;
67
+static uint32_t
61
68
+igb_rxhdrbufsize(IGBCore *core, const E1000ERingInfo *r)
62
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
69
+{
63
SocketReadState sec_rs;
70
+ uint32_t srrctl = core->mac[E1000_SRRCTL(r->idx) >> 2];
64
bool vnet_hdr;
71
+ return (srrctl & E1000_SRRCTL_BSIZEHDRSIZE_MASK) >>
65
72
+ E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
66
- /* connection list: the connections belonged to this NIC could be found
73
+}
67
- * in this list.
74
+
68
- * element type: Connection
75
void
69
+ /*
76
igb_start_recv(IGBCore *core)
70
+ * Record the connection that through the NIC
77
{
71
+ * Element type: Connection
78
@@ -XXX,XX +XXX,XX @@ igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
72
*/
79
*buff_addr = le64_to_cpu(desc->read.pkt_addr);
73
GQueue conn_list;
80
}
74
- /* hashtable to save connection */
81
75
+ /* Record the connection without repetition */
82
+typedef struct IGBPacketRxDMAState {
76
GHashTable *connection_track_table;
83
+ size_t size;
77
- /* compare thread, a thread for each NIC */
84
+ size_t total_size;
78
+ /* This thread just do packet compare job */
85
+ size_t ps_hdr_len;
79
QemuThread thread;
86
+ size_t desc_size;
80
87
+ size_t desc_offset;
81
GMainContext *worker_context;
88
+ uint32_t rx_desc_packet_buf_size;
82
@@ -XXX,XX +XXX,XX @@ static int colo_old_packet_check_one_conn(Connection *conn,
89
+ uint32_t rx_desc_header_buf_size;
83
(GCompareFunc)colo_old_packet_check_one);
90
+ struct iovec *iov;
84
91
+ size_t iov_ofs;
85
if (result) {
92
+ bool is_first;
86
- /* do checkpoint will flush old packet */
93
+ uint16_t written;
87
- /* TODO: colo_notify_checkpoint();*/
94
+ hwaddr ba;
88
+ /* Do checkpoint will flush old packet */
95
+} IGBPacketRxDMAState;
89
+ /*
96
+
90
+ * TODO: Notify colo frame to do checkpoint.
97
static inline void
91
+ * colo_compare_inconsistent_notify();
98
igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
92
+ */
99
hwaddr *buff_addr)
93
return 0;
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;
94
}
244
}
95
245
246
do {
247
- hwaddr ba;
248
- uint16_t written = 0;
249
+ pdma_st.written = 0;
250
bool is_last = false;
251
252
- desc_size = total_size - desc_offset;
253
-
254
- if (desc_size > bufsize) {
255
- desc_size = bufsize;
256
- }
257
-
258
if (igb_ring_empty(core, rxi)) {
259
return;
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);
96
--
347
--
97
2.7.4
348
2.7.4
98
99
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
The packet_enqueue() use g_queue_push_tail() to
3
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
4
enqueue net packet, so it is more efficent way use
4
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
g_queue_pop_head() to get packet for compare.
5
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
That will improve the success rate of comparison.
7
In my test the performance of ftp put 1000M file
8
will increase 10%
9
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
7
---
13
net/colo-compare.c | 4 ++--
8
hw/net/igb_core.c | 4 +++-
14
1 file changed, 2 insertions(+), 2 deletions(-)
9
hw/net/igb_regs.h | 1 +
10
2 files changed, 4 insertions(+), 1 deletion(-)
15
11
16
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/net/colo-compare.c
14
--- a/hw/net/igb_core.c
19
+++ b/net/colo-compare.c
15
+++ b/hw/net/igb_core.c
20
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
16
@@ -XXX,XX +XXX,XX @@ igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
21
17
net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
22
while (!g_queue_is_empty(&conn->primary_list) &&
18
23
!g_queue_is_empty(&conn->secondary_list)) {
19
if (hasip6 && !(core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
24
- pkt = g_queue_pop_tail(&conn->primary_list);
20
- pkt_type = E1000_ADVRXD_PKT_IP6;
25
+ pkt = g_queue_pop_head(&conn->primary_list);
21
+ eth_ip6_hdr_info *ip6hdr_info = net_rx_pkt_get_ip6_info(pkt);
26
switch (conn->ip_proto) {
22
+ pkt_type = ip6hdr_info->has_ext_hdrs ? E1000_ADVRXD_PKT_IP6E :
27
case IPPROTO_TCP:
23
+ E1000_ADVRXD_PKT_IP6;
28
result = g_queue_find_custom(&conn->secondary_list,
24
} else if (hasip4) {
29
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
25
pkt_type = E1000_ADVRXD_PKT_IP4;
30
* until next comparison.
26
} else {
31
*/
27
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
32
trace_colo_compare_main("packet different");
28
index XXXXXXX..XXXXXXX 100644
33
- g_queue_push_tail(&conn->primary_list, pkt);
29
--- a/hw/net/igb_regs.h
34
+ g_queue_push_head(&conn->primary_list, pkt);
30
+++ b/hw/net/igb_regs.h
35
/* TODO: colo_notify_checkpoint();*/
31
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
36
break;
32
37
}
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)
38
--
39
--
39
2.7.4
40
2.7.4
40
41
diff view generated by jsdifflib
1
From: Matt Parker <mtparkr@gmail.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
Both io and memory use the same mmio functions in the rtl8139 device.
3
Packet-split descriptors are used by Linux VF driver for MTU values from 2048
4
This patch removes the separate MemoryRegionOps and old_mmio accessors
5
for memory, and replaces it with an alias to the io memory region.
6
4
7
Signed-off-by: Matt Parker <mtparkr@gmail.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>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
9
---
10
hw/net/rtl8139.c | 53 +++--------------------------------------------------
10
hw/net/igb_core.c | 348 +++++++++++++++++++++++++++++++++++++++++++++-------
11
1 file changed, 3 insertions(+), 50 deletions(-)
11
hw/net/igb_regs.h | 9 ++
12
hw/net/trace-events | 2 +-
13
3 files changed, 316 insertions(+), 43 deletions(-)
12
14
13
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
15
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/rtl8139.c
17
--- a/hw/net/igb_core.c
16
+++ b/hw/net/rtl8139.c
18
+++ b/hw/net/igb_core.c
17
@@ -XXX,XX +XXX,XX @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
19
@@ -XXX,XX +XXX,XX @@ igb_rx_use_legacy_descriptor(IGBCore *core)
18
20
return false;
19
/* */
21
}
20
22
21
-static void rtl8139_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
23
+typedef struct E1000ERingInfo {
22
-{
24
+ int dbah;
23
- rtl8139_io_writeb(opaque, addr & 0xFF, val);
25
+ int dbal;
24
-}
26
+ int dlen;
27
+ int dh;
28
+ int dt;
29
+ int idx;
30
+} E1000ERingInfo;
31
+
32
+static uint32_t
33
+igb_rx_queue_desctyp_get(IGBCore *core, const E1000ERingInfo *r)
34
+{
35
+ return core->mac[E1000_SRRCTL(r->idx) >> 2] & E1000_SRRCTL_DESCTYPE_MASK;
36
+}
37
+
38
+static bool
39
+igb_rx_use_ps_descriptor(IGBCore *core, const E1000ERingInfo *r)
40
+{
41
+ uint32_t desctyp = igb_rx_queue_desctyp_get(core, r);
42
+ return desctyp == E1000_SRRCTL_DESCTYPE_HDR_SPLIT ||
43
+ desctyp == E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
44
+}
45
+
46
static inline bool
47
igb_rss_enabled(IGBCore *core)
48
{
49
@@ -XXX,XX +XXX,XX @@ static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx)
50
return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
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;
25
-
61
-
26
-static void rtl8139_mmio_writew(void *opaque, hwaddr addr, uint32_t val)
62
static inline bool
27
-{
63
igb_ring_empty(IGBCore *core, const E1000ERingInfo *r)
28
- rtl8139_io_writew(opaque, addr & 0xFF, val);
64
{
29
-}
65
@@ -XXX,XX +XXX,XX @@ igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
30
-
66
}
31
-static void rtl8139_mmio_writel(void *opaque, hwaddr addr, uint32_t val)
67
32
-{
68
static inline void
33
- rtl8139_io_writel(opaque, addr & 0xFF, val);
69
-igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
34
-}
70
- hwaddr *buff_addr)
35
-
71
+igb_read_adv_rx_single_buf_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
36
-static uint32_t rtl8139_mmio_readb(void *opaque, hwaddr addr)
72
+ hwaddr *buff_addr)
37
-{
73
{
38
- return rtl8139_io_readb(opaque, addr & 0xFF);
74
*buff_addr = le64_to_cpu(desc->read.pkt_addr);
39
-}
75
}
40
-
76
41
-static uint32_t rtl8139_mmio_readw(void *opaque, hwaddr addr)
77
+static inline void
42
-{
78
+igb_read_adv_rx_split_buf_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
43
- uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
79
+ hwaddr *buff_addr)
44
- return val;
80
+{
45
-}
81
+ buff_addr[0] = le64_to_cpu(desc->read.hdr_addr);
46
-
82
+ buff_addr[1] = le64_to_cpu(desc->read.pkt_addr);
47
-static uint32_t rtl8139_mmio_readl(void *opaque, hwaddr addr)
83
+}
48
-{
84
+
49
- uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
85
+typedef struct IGBBAState {
50
- return val;
86
+ uint16_t written[IGB_MAX_PS_BUFFERS];
51
-}
87
+ uint8_t cur_idx;
52
-
88
+} IGBBAState;
53
static int rtl8139_post_load(void *opaque, int version_id)
89
+
54
{
90
+typedef struct IGBSplitDescriptorData {
55
RTL8139State* s = opaque;
91
+ bool sph;
56
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps rtl8139_io_ops = {
92
+ bool hbo;
57
.endianness = DEVICE_LITTLE_ENDIAN,
93
+ size_t hdr_len;
58
};
94
+} IGBSplitDescriptorData;
59
95
+
60
-static const MemoryRegionOps rtl8139_mmio_ops = {
96
typedef struct IGBPacketRxDMAState {
61
- .old_mmio = {
97
size_t size;
62
- .read = {
98
size_t total_size;
63
- rtl8139_mmio_readb,
99
@@ -XXX,XX +XXX,XX @@ typedef struct IGBPacketRxDMAState {
64
- rtl8139_mmio_readw,
100
uint32_t rx_desc_header_buf_size;
65
- rtl8139_mmio_readl,
101
struct iovec *iov;
66
- },
102
size_t iov_ofs;
67
- .write = {
103
+ bool do_ps;
68
- rtl8139_mmio_writeb,
104
bool is_first;
69
- rtl8139_mmio_writew,
105
- uint16_t written;
70
- rtl8139_mmio_writel,
106
- hwaddr ba;
71
- },
107
+ IGBBAState bastate;
72
- },
108
+ hwaddr ba[IGB_MAX_PS_BUFFERS];
73
- .endianness = DEVICE_LITTLE_ENDIAN,
109
+ IGBSplitDescriptorData ps_desc_data;
74
-};
110
} IGBPacketRxDMAState;
75
-
111
76
static void rtl8139_timer(void *opaque)
112
static inline void
77
{
113
-igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
78
RTL8139State *s = opaque;
114
- hwaddr *buff_addr)
79
@@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
115
+igb_read_rx_descr(IGBCore *core,
80
116
+ union e1000_rx_desc_union *desc,
81
memory_region_init_io(&s->bar_io, OBJECT(s), &rtl8139_io_ops, s,
117
+ IGBPacketRxDMAState *pdma_st,
82
"rtl8139", 0x100);
118
+ const E1000ERingInfo *r)
83
- memory_region_init_io(&s->bar_mem, OBJECT(s), &rtl8139_mmio_ops, s,
119
{
84
- "rtl8139", 0x100);
120
+ uint32_t desc_type;
85
+ memory_region_init_alias(&s->bar_mem, OBJECT(s), "rtl8139-mem", &s->bar_io,
121
+
86
+ 0, 0x100);
122
if (igb_rx_use_legacy_descriptor(core)) {
87
+
123
- igb_read_lgcy_rx_descr(core, &desc->legacy, buff_addr);
88
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io);
124
- } else {
89
pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem);
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"
90
532
91
--
533
--
92
2.7.4
534
2.7.4
93
94
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
Currently, net_socket_mcast_create(), net_socket_fd_init_dgram() and
3
Rename e1000e_ba_state according and e1000e_write_hdr_to_rx_buffers for
4
net_socket_fd_init() use the function such as fprintf(), perror() to
4
consistency with IGB.
5
report an error message.
6
5
7
Now, convert these functions to Error.
6
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
8
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Cc: jasowang@redhat.com
8
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Cc: armbru@redhat.com
11
Cc: berrange@redhat.com
12
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
13
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
10
---
17
net/socket.c | 82 ++++++++++++++++++++++++++++++++++++------------------------
11
hw/net/e1000e_core.c | 28 +++++++++++++++-------------
18
1 file changed, 50 insertions(+), 32 deletions(-)
12
1 file changed, 15 insertions(+), 13 deletions(-)
19
13
20
diff --git a/net/socket.c b/net/socket.c
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/net/socket.c
16
--- a/hw/net/e1000e_core.c
23
+++ b/net/socket.c
17
+++ b/hw/net/e1000e_core.c
24
@@ -XXX,XX +XXX,XX @@ static void net_socket_send_dgram(void *opaque)
18
@@ -XXX,XX +XXX,XX @@ e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
25
}
19
}
26
}
20
}
27
21
28
-static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
22
-typedef struct e1000e_ba_state_st {
29
+static int net_socket_mcast_create(struct sockaddr_in *mcastaddr,
23
+typedef struct E1000EBAState {
30
+ struct in_addr *localaddr,
24
uint16_t written[MAX_PS_BUFFERS];
31
+ Error **errp)
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)
32
{
40
{
33
struct ip_mreq imr;
41
assert(data_len <= core->rxbuf_sizes[0] - bastate->written[0]);
34
int fd;
42
35
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
43
@@ -XXX,XX +XXX,XX @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
36
#endif
44
static void
37
45
e1000e_write_payload_frag_to_rx_buffers(E1000ECore *core,
38
if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
46
hwaddr ba[MAX_PS_BUFFERS],
39
- fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) "
47
- e1000e_ba_state *bastate,
40
- "does not contain a multicast address\n",
48
+ E1000EBAState *bastate,
41
- inet_ntoa(mcastaddr->sin_addr),
49
const char *data,
42
- (int)ntohl(mcastaddr->sin_addr.s_addr));
50
dma_addr_t data_len)
43
+ error_setg(errp, "specified mcastaddr %s (0x%08x) "
44
+ "does not contain a multicast address",
45
+ inet_ntoa(mcastaddr->sin_addr),
46
+ (int)ntohl(mcastaddr->sin_addr.s_addr));
47
return -1;
48
-
49
}
50
+
51
fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);
52
if (fd < 0) {
53
- perror("socket(PF_INET, SOCK_DGRAM)");
54
+ error_setg_errno(errp, errno, "can't create datagram socket");
55
return -1;
56
}
57
58
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
59
val = 1;
60
ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
61
if (ret < 0) {
62
- perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
63
+ error_setg_errno(errp, errno,
64
+ "can't set socket option SO_REUSEADDR");
65
goto fail;
66
}
67
68
ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
69
if (ret < 0) {
70
- perror("bind");
71
+ error_setg_errno(errp, errno, "can't bind ip=%s to socket",
72
+ inet_ntoa(mcastaddr->sin_addr));
73
goto fail;
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
77
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
78
&imr, sizeof(struct ip_mreq));
79
if (ret < 0) {
80
- perror("setsockopt(IP_ADD_MEMBERSHIP)");
81
+ error_setg_errno(errp, errno,
82
+ "can't add socket to multicast group %s",
83
+ inet_ntoa(imr.imr_multiaddr));
84
goto fail;
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
88
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
89
&loop, sizeof(loop));
90
if (ret < 0) {
91
- perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
92
+ error_setg_errno(errp, errno,
93
+ "can't force multicast message to loopback");
94
goto fail;
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
98
ret = qemu_setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
99
localaddr, sizeof(*localaddr));
100
if (ret < 0) {
101
- perror("setsockopt(IP_MULTICAST_IF)");
102
+ error_setg_errno(errp, errno,
103
+ "can't set the default network send interface");
104
goto fail;
105
}
106
}
107
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
108
const char *model,
109
const char *name,
110
int fd, int is_connected,
111
- const char *mcast)
112
+ const char *mcast,
113
+ Error **errp)
114
{
51
{
115
struct sockaddr_in saddr;
52
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
116
int newfd;
53
117
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
54
do {
118
55
hwaddr ba[MAX_PS_BUFFERS];
119
if (is_connected && mcast != NULL) {
56
- e1000e_ba_state bastate = { { 0 } };
120
if (parse_host_port(&saddr, mcast) < 0) {
57
+ E1000EBAState bastate = { { 0 } };
121
- fprintf(stderr,
58
bool is_last = false;
122
- "qemu: error: init_dgram: fd=%d failed parse_host_port()\n",
59
123
- fd);
60
desc_size = total_size - desc_offset;
124
+ error_setg(errp, "fd=%d failed parse_host_port()", fd);
61
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
125
goto err;
62
iov_copy = MIN(ps_hdr_len - ps_hdr_copied,
126
}
63
iov->iov_len - iov_ofs);
127
/* must be bound */
64
128
if (saddr.sin_addr.s_addr == 0) {
65
- e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
129
- fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
66
- iov->iov_base, iov_copy);
130
- "cannot setup multicast dst addr\n", fd);
67
+ e1000e_write_hdr_frag_to_rx_buffers(core, ba,
131
+ error_setg(errp, "can't setup multicast destination address");
68
+ &bastate,
132
goto err;
69
+ iov->iov_base,
133
}
70
+ iov_copy);
134
/* clone dgram socket */
71
135
- newfd = net_socket_mcast_create(&saddr, NULL);
72
copy_size -= iov_copy;
136
+ newfd = net_socket_mcast_create(&saddr, NULL, errp);
73
ps_hdr_copied += iov_copy;
137
if (newfd < 0) {
74
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
138
- /* error already reported by net_socket_mcast_create() */
75
} else {
139
goto err;
76
/* Leave buffer 0 of each descriptor except first */
140
}
77
/* empty as per spec 7.1.5.1 */
141
/* clone newfd to fd, close newfd */
78
- e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
142
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
79
- NULL, 0);
143
80
+ e1000e_write_hdr_frag_to_rx_buffers(core, ba, &bastate,
144
static NetSocketState *net_socket_fd_init(NetClientState *peer,
81
+ NULL, 0);
145
const char *model, const char *name,
82
}
146
- int fd, int is_connected, const char *mc)
83
}
147
+ int fd, int is_connected,
84
148
+ const char *mc, Error **errp)
149
{
150
int so_type = -1, optlen=sizeof(so_type);
151
152
if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
153
(socklen_t *)&optlen)< 0) {
154
- fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n",
155
- fd);
156
+ error_setg(errp, "can't get socket option SO_TYPE");
157
closesocket(fd);
158
return NULL;
159
}
160
switch(so_type) {
161
case SOCK_DGRAM:
162
- return net_socket_fd_init_dgram(peer, model, name, fd, is_connected, mc);
163
+ return net_socket_fd_init_dgram(peer, model, name, fd, is_connected,
164
+ mc, errp);
165
case SOCK_STREAM:
166
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
167
default:
168
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
169
NetSocketState *s;
170
int fd, connected, ret;
171
struct sockaddr_in saddr;
172
+ Error *err = NULL;
173
174
if (parse_host_port(&saddr, host_str) < 0)
175
return -1;
176
@@ -XXX,XX +XXX,XX @@ static int net_socket_connect_init(NetClientState *peer,
177
break;
178
}
179
}
180
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL);
181
- if (!s)
182
+ s = net_socket_fd_init(peer, model, name, fd, connected, NULL, &err);
183
+ if (!s) {
184
+ error_report_err(err);
185
return -1;
186
+ }
187
+
188
snprintf(s->nc.info_str, sizeof(s->nc.info_str),
189
"socket: connect to %s:%d",
190
inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
191
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
192
int fd;
193
struct sockaddr_in saddr;
194
struct in_addr localaddr, *param_localaddr;
195
+ Error *err = NULL;
196
197
if (parse_host_port(&saddr, host_str) < 0)
198
return -1;
199
@@ -XXX,XX +XXX,XX @@ static int net_socket_mcast_init(NetClientState *peer,
200
param_localaddr = NULL;
201
}
202
203
- fd = net_socket_mcast_create(&saddr, param_localaddr);
204
- if (fd < 0)
205
+ fd = net_socket_mcast_create(&saddr, param_localaddr, &err);
206
+ if (fd < 0) {
207
+ error_report_err(err);
208
return -1;
209
+ }
210
211
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL);
212
- if (!s)
213
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
214
+ if (!s) {
215
+ error_report_err(err);
216
return -1;
217
+ }
218
219
s->dgram_dst = saddr;
220
221
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
222
NetSocketState *s;
223
int fd, ret;
224
struct sockaddr_in laddr, raddr;
225
+ Error *err = NULL;
226
227
if (parse_host_port(&laddr, lhost) < 0) {
228
return -1;
229
@@ -XXX,XX +XXX,XX @@ static int net_socket_udp_init(NetClientState *peer,
230
}
231
qemu_set_nonblock(fd);
232
233
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL);
234
+ s = net_socket_fd_init(peer, model, name, fd, 0, NULL, &err);
235
if (!s) {
236
+ error_report_err(err);
237
return -1;
238
}
239
240
@@ -XXX,XX +XXX,XX @@ int net_init_socket(const Netdev *netdev, const char *name,
241
return -1;
242
}
243
qemu_set_nonblock(fd);
244
- if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast)) {
245
+ if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
246
+ errp)) {
247
return -1;
248
}
249
return 0;
250
--
85
--
251
2.7.4
86
2.7.4
252
253
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
My Fujitsu mail account will be disabled soon, update the mail info
3
AF_XDP is a network socket family that allows communication directly
4
to my private mail.
4
with the network device driver in the kernel, bypassing most or all
5
5
of the kernel networking stack. In the essence, the technology is
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
pretty similar to netmap. But, unlike netmap, AF_XDP is Linux-native
7
and works with any network interfaces without driver modifications.
8
Unlike vhost-based backends (kernel, user, vdpa), AF_XDP doesn't
9
require access to character devices or unix sockets. Only access to
10
the network interface itself is necessary.
11
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>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
135
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
136
---
9
MAINTAINERS | 2 +-
137
MAINTAINERS | 4 +
10
1 file changed, 1 insertion(+), 1 deletion(-)
138
hmp-commands.hx | 3 +
139
meson.build | 9 +
140
meson_options.txt | 2 +
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
11
152
12
diff --git a/MAINTAINERS b/MAINTAINERS
153
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
154
index XXXXXXX..XXXXXXX 100644
14
--- a/MAINTAINERS
155
--- a/MAINTAINERS
15
+++ b/MAINTAINERS
156
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ F: include/migration/failover.h
157
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
17
F: docs/COLO-FT.txt
158
S: Maintained
18
159
F: net/netmap.c
19
COLO Proxy
160
20
-M: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
161
+AF_XDP network backend
21
+M: Zhang Chen <zhangckid@gmail.com>
162
+R: Ilya Maximets <i.maximets@ovn.org>
22
M: Li Zhijian <lizhijian@cn.fujitsu.com>
163
+F: net/af-xdp.c
23
S: Supported
164
+
24
F: docs/colo-proxy.txt
165
Host Memory Backends
166
M: David Hildenbrand <david@redhat.com>
167
M: Igor Mammedov <imammedo@redhat.com>
168
diff --git a/hmp-commands.hx b/hmp-commands.hx
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hmp-commands.hx
171
+++ b/hmp-commands.hx
172
@@ -XXX,XX +XXX,XX @@ ERST
173
.name = "netdev_add",
174
.args_type = "netdev:O",
175
.params = "[user|tap|socket|stream|dgram|vde|bridge|hubport|netmap|vhost-user"
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)) {
394
+ /*
395
+ * Out of buffers or space in tx ring. Poll until we can write.
396
+ * This will also kick the Tx, if it was waiting on CQ.
397
+ */
398
+ af_xdp_write_poll(s, true);
399
+ return 0;
400
+ }
401
+
402
+ desc = xsk_ring_prod__tx_desc(&s->tx, idx);
403
+ desc->addr = s->pool[--s->n_pool];
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);
735
+ goto err;
736
+ }
737
+ }
738
+
739
+ if (nc0) {
740
+ s = DO_UPCAST(AFXDPState, nc, nc0);
741
+ if (bpf_xdp_query_id(s->ifindex, s->xdp_flags, &prog_id) || !prog_id) {
742
+ error_setg_errno(errp, errno,
743
+ "no XDP program loaded on '%s', ifindex: %d",
744
+ s->ifname, s->ifindex);
745
+ goto err;
746
+ }
747
+ }
748
+
749
+ af_xdp_read_poll(s, true); /* Initially only poll for reads. */
750
+
751
+ return 0;
752
+
753
+err:
754
+ g_free(sock_fds);
755
+ if (nc0) {
756
+ qemu_del_net_client(nc0);
757
+ }
758
+
759
+ return -1;
760
+}
761
diff --git a/net/clients.h b/net/clients.h
762
index XXXXXXX..XXXXXXX 100644
763
--- a/net/clients.h
764
+++ b/net/clients.h
765
@@ -XXX,XX +XXX,XX @@ int net_init_netmap(const Netdev *netdev, const char *name,
766
NetClientState *peer, Error **errp);
767
#endif
768
769
+#ifdef CONFIG_AF_XDP
770
+int net_init_af_xdp(const Netdev *netdev, const char *name,
771
+ NetClientState *peer, Error **errp);
772
+#endif
773
+
774
int net_init_vhost_user(const Netdev *netdev, const char *name,
775
NetClientState *peer, Error **errp);
776
777
diff --git a/net/meson.build b/net/meson.build
778
index XXXXXXX..XXXXXXX 100644
779
--- a/net/meson.build
780
+++ b/net/meson.build
781
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: vde, if_true: files('vde.c'))
782
if have_netmap
783
system_ss.add(files('netmap.c'))
784
endif
785
+
786
+system_ss.add(when: libxdp, if_true: files('af-xdp.c'))
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',
905
diff --git a/qemu-options.hx b/qemu-options.hx
906
index XXXXXXX..XXXXXXX 100644
907
--- a/qemu-options.hx
908
+++ b/qemu-options.hx
909
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
910
" VALE port (created on the fly) called 'name' ('nmname' is name of the \n"
911
" netmap device, defaults to '/dev/netmap')\n"
912
#endif
913
+#ifdef CONFIG_AF_XDP
914
+ "-netdev af-xdp,id=str,ifname=name[,mode=native|skb][,force-copy=on|off]\n"
915
+ " [,queues=n][,start-queue=m][,inhibit=on|off][,sock-fds=x:y:...:z]\n"
916
+ " attach to the existing network interface 'name' with AF_XDP socket\n"
917
+ " use 'mode=MODE' to specify an XDP program attach mode\n"
918
+ " use 'force-copy=on|off' to force XDP copy mode even if device supports zero-copy (default: off)\n"
919
+ " use 'inhibit=on|off' to inhibit loading of a default XDP program (default: off)\n"
920
+ " with inhibit=on,\n"
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 \
25
--
1059
--
26
2.7.4
1060
2.7.4
27
28
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
Memory allocation functions like world_alloc, desc_ring_alloc etc,
3
Changed eBPF map updates through mmaped array.
4
they are all wrappers around g_malloc, g_new etc. But g_malloc and
4
Mmaped arrays provide direct access to map data.
5
similar functions doesn't return null. Because they ignore the fact
5
It should omit using bpf_map_update_elem() call,
6
that g_malloc() of 0 bytes returns null. So error checks for these
6
which may require capabilities that are not present.
7
allocation failure are superfluous. Now, remove them entirely.
8
7
9
Cc: jasowang@redhat.com
8
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
10
Cc: jiri@resnulli.us
11
Cc: armbru@redhat.com
12
Cc: f4bug@amsat.org
13
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
10
---
17
hw/net/rocker/rocker.c | 47 +------------------------------------------
11
ebpf/ebpf_rss.c | 117 +++++++++++++++++++++++++++++++++++++++++++++-----------
18
hw/net/rocker/rocker_desc.c | 10 ---------
12
ebpf/ebpf_rss.h | 5 +++
19
hw/net/rocker/rocker_fp.c | 4 ----
13
2 files changed, 99 insertions(+), 23 deletions(-)
20
hw/net/rocker/rocker_of_dpa.c | 20 ------------------
21
hw/net/rocker/rocker_world.c | 12 +++++------
22
5 files changed, 6 insertions(+), 87 deletions(-)
23
14
24
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
15
diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/net/rocker/rocker.c
17
--- a/ebpf/ebpf_rss.c
27
+++ b/hw/net/rocker/rocker.c
18
+++ b/ebpf/ebpf_rss.c
28
@@ -XXX,XX +XXX,XX @@ static int tx_consume(Rocker *r, DescInfo *info)
19
@@ -XXX,XX +XXX,XX @@ void ebpf_rss_init(struct EBPFRSSContext *ctx)
29
}
20
{
30
iov[iovcnt].iov_len = frag_len;
21
if (ctx != NULL) {
31
iov[iovcnt].iov_base = g_malloc(frag_len);
22
ctx->obj = NULL;
32
- if (!iov[iovcnt].iov_base) {
23
+ ctx->program_fd = -1;
33
- err = -ROCKER_ENOMEM;
24
+ ctx->map_configuration = -1;
34
- goto err_no_mem;
25
+ ctx->map_toeplitz_key = -1;
35
- }
26
+ ctx->map_indirections_table = -1;
36
27
+
37
pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,
28
+ ctx->mmap_configuration = NULL;
38
iov[iovcnt].iov_len);
29
+ ctx->mmap_toeplitz_key = NULL;
39
@@ -XXX,XX +XXX,XX @@ static int tx_consume(Rocker *r, DescInfo *info)
30
+ ctx->mmap_indirections_table = NULL;
40
err = fp_port_eg(r->fp_port[port], iov, iovcnt);
31
}
41
32
}
42
err_too_many_frags:
33
43
-err_no_mem:
34
bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx)
44
err_bad_attr:
35
{
45
for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {
36
- return ctx != NULL && ctx->obj != NULL;
46
g_free(iov[i].iov_base);
37
+ return ctx != NULL && (ctx->obj != NULL || ctx->program_fd != -1);
47
@@ -XXX,XX +XXX,XX @@ int rx_produce(World *world, uint32_t pport,
38
+}
48
*/
39
+
49
40
+static bool ebpf_rss_mmap(struct EBPFRSSContext *ctx)
50
data = g_malloc(data_size);
41
+{
51
- if (!data) {
42
+ if (!ebpf_rss_is_loaded(ctx)) {
52
- err = -ROCKER_ENOMEM;
43
+ return false;
53
- goto out;
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;
79
+}
80
+
81
+static void ebpf_rss_munmap(struct EBPFRSSContext *ctx)
82
+{
83
+ if (!ebpf_rss_is_loaded(ctx)) {
84
+ return;
85
+ }
86
+
87
+ munmap(ctx->mmap_indirections_table, qemu_real_host_page_size());
88
+ munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
89
+ munmap(ctx->mmap_configuration, qemu_real_host_page_size());
90
+
91
+ ctx->mmap_configuration = NULL;
92
+ ctx->mmap_toeplitz_key = NULL;
93
+ ctx->mmap_indirections_table = NULL;
94
}
95
96
bool ebpf_rss_load(struct EBPFRSSContext *ctx)
97
{
98
struct rss_bpf *rss_bpf_ctx;
99
100
- if (ctx == NULL) {
101
+ if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
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;
54
- }
136
- }
55
+
137
+
56
iov_to_buf(iov, iovcnt, 0, data, data_size);
138
+ memcpy(ctx->mmap_configuration, config, sizeof(*config));
57
pci_dma_write(dev, frag_addr, data, data_size);
139
return true;
58
g_free(data);
140
}
59
@@ -XXX,XX +XXX,XX @@ static void rocker_test_dma_ctrl(Rocker *r, uint32_t val)
141
60
142
@@ -XXX,XX +XXX,XX @@ static bool ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
61
buf = g_malloc(r->test_dma_size);
143
uint16_t *indirections_table,
62
144
size_t len)
63
- if (!buf) {
145
{
64
- DPRINTF("test dma buffer alloc failed");
146
- uint32_t i = 0;
65
- return;
66
- }
67
-
147
-
68
switch (val) {
148
if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
69
case ROCKER_TEST_DMA_CTRL_CLEAR:
149
len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
70
memset(buf, 0, r->test_dma_size);
150
return false;
71
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
151
}
72
152
73
r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);
153
- for (; i < len; ++i) {
74
154
- if (bpf_map_update_elem(ctx->map_indirections_table, &i,
75
- for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
155
- indirections_table + i, 0) < 0) {
76
- if (!r->worlds[i]) {
156
- return false;
77
- err = -ENOMEM;
78
- goto err_world_alloc;
79
- }
157
- }
80
- }
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;
81
-
168
-
82
if (!r->world_name) {
169
/* prepare toeplitz key */
83
r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));
170
uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};
84
}
171
85
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
172
@@ -XXX,XX +XXX,XX @@ static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
86
}
173
memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
87
174
*(uint32_t *)toe = ntohl(*(uint32_t *)toe);
88
r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
175
89
- if (!r->rings) {
176
- if (bpf_map_update_elem(ctx->map_toeplitz_key, &map_key, toe,
90
- goto err_rings_alloc;
177
- 0) < 0) {
91
- }
92
93
/* Rings are ordered like this:
94
* - command ring
95
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
96
* .....
97
*/
98
99
- err = -ENOMEM;
100
for (i = 0; i < rocker_pci_ring_count(r); i++) {
101
DescRing *ring = desc_ring_alloc(r, i);
102
103
- if (!ring) {
104
- goto err_ring_alloc;
105
- }
106
-
107
if (i == ROCKER_RING_CMD) {
108
desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);
109
} else if (i == ROCKER_RING_EVENT) {
110
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
111
fp_port_alloc(r, r->name, &r->fp_start_macaddr,
112
i, &r->fp_ports_peers[i]);
113
114
- if (!port) {
115
- goto err_port_alloc;
116
- }
117
-
118
r->fp_port[i] = port;
119
fp_port_set_world(port, r->world_dflt);
120
}
121
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
122
123
return 0;
124
125
-err_port_alloc:
126
- for (--i; i >= 0; i--) {
127
- FpPort *port = r->fp_port[i];
128
- fp_port_free(port);
129
- }
130
- i = rocker_pci_ring_count(r);
131
-err_ring_alloc:
132
- for (--i; i >= 0; i--) {
133
- desc_ring_free(r->rings[i]);
134
- }
135
- g_free(r->rings);
136
-err_rings_alloc:
137
err_duplicate:
138
rocker_msix_uninit(r);
139
err_msix_init:
140
object_unparent(OBJECT(&r->msix_bar));
141
object_unparent(OBJECT(&r->mmio));
142
err_world_type_by_name:
143
-err_world_alloc:
144
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
145
if (r->worlds[i]) {
146
world_free(r->worlds[i]);
147
diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/net/rocker/rocker_desc.c
150
+++ b/hw/net/rocker/rocker_desc.c
151
@@ -XXX,XX +XXX,XX @@ char *desc_get_buf(DescInfo *info, bool read_only)
152
info->buf_size = size;
153
}
154
155
- if (!info->buf) {
156
- return NULL;
157
- }
158
-
159
pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size);
160
161
return info->buf;
162
@@ -XXX,XX +XXX,XX @@ bool desc_ring_set_size(DescRing *ring, uint32_t size)
163
ring->head = ring->tail = 0;
164
165
ring->info = g_renew(DescInfo, ring->info, size);
166
- if (!ring->info) {
167
- return false;
178
- return false;
168
- }
179
- }
169
180
+ memcpy(ctx->mmap_toeplitz_key, toe, VIRTIO_NET_RSS_MAX_KEY_SIZE);
170
memset(ring->info, 0, size * sizeof(DescInfo));
181
return true;
171
182
}
172
@@ -XXX,XX +XXX,XX @@ DescRing *desc_ring_alloc(Rocker *r, int index)
183
173
DescRing *ring;
184
@@ -XXX,XX +XXX,XX @@ void ebpf_rss_unload(struct EBPFRSSContext *ctx)
174
185
return;
175
ring = g_new0(DescRing, 1);
186
}
176
- if (!ring) {
187
177
- return NULL;
188
- rss_bpf__destroy(ctx->obj);
178
- }
189
+ ebpf_rss_munmap(ctx);
179
190
+
180
ring->r = r;
191
+ if (ctx->obj) {
181
ring->index = index;
192
+ rss_bpf__destroy(ctx->obj);
182
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
193
+ } else {
194
+ close(ctx->program_fd);
195
+ close(ctx->map_configuration);
196
+ close(ctx->map_toeplitz_key);
197
+ close(ctx->map_indirections_table);
198
+ }
199
+
200
ctx->obj = NULL;
201
+ ctx->program_fd = -1;
202
+ ctx->map_configuration = -1;
203
+ ctx->map_toeplitz_key = -1;
204
+ ctx->map_indirections_table = -1;
205
}
206
diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
183
index XXXXXXX..XXXXXXX 100644
207
index XXXXXXX..XXXXXXX 100644
184
--- a/hw/net/rocker/rocker_fp.c
208
--- a/ebpf/ebpf_rss.h
185
+++ b/hw/net/rocker/rocker_fp.c
209
+++ b/ebpf/ebpf_rss.h
186
@@ -XXX,XX +XXX,XX @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
210
@@ -XXX,XX +XXX,XX @@ struct EBPFRSSContext {
187
{
211
int map_configuration;
188
FpPort *port = g_new0(FpPort, 1);
212
int map_toeplitz_key;
189
213
int map_indirections_table;
190
- if (!port) {
214
+
191
- return NULL;
215
+ /* mapped eBPF maps for direct access to omit bpf_map_update_elem() */
192
- }
216
+ void *mmap_configuration;
193
-
217
+ void *mmap_toeplitz_key;
194
port->r = r;
218
+ void *mmap_indirections_table;
195
port->index = index;
219
};
196
port->pport = index + 1;
220
197
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
221
struct EBPFRSSConfig {
198
index XXXXXXX..XXXXXXX 100644
199
--- a/hw/net/rocker/rocker_of_dpa.c
200
+++ b/hw/net/rocker/rocker_of_dpa.c
201
@@ -XXX,XX +XXX,XX @@ static OfDpaFlow *of_dpa_flow_alloc(uint64_t cookie)
202
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
203
204
flow = g_new0(OfDpaFlow, 1);
205
- if (!flow) {
206
- return NULL;
207
- }
208
209
flow->cookie = cookie;
210
flow->mask.tbl_id = 0xffffffff;
211
@@ -XXX,XX +XXX,XX @@ static OfDpaGroup *of_dpa_group_alloc(uint32_t id)
212
{
213
OfDpaGroup *group = g_new0(OfDpaGroup, 1);
214
215
- if (!group) {
216
- return NULL;
217
- }
218
-
219
group->id = id;
220
221
return group;
222
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_flow_add(OfDpa *of_dpa, uint64_t cookie,
223
}
224
225
flow = of_dpa_flow_alloc(cookie);
226
- if (!flow) {
227
- return -ROCKER_ENOMEM;
228
- }
229
230
err = of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);
231
if (err) {
232
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
233
rocker_tlv_get_le16(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT]);
234
235
tlvs = g_new0(RockerTlv *, group->l2_flood.group_count + 1);
236
- if (!tlvs) {
237
- return -ROCKER_ENOMEM;
238
- }
239
240
g_free(group->l2_flood.group_ids);
241
group->l2_flood.group_ids =
242
g_new0(uint32_t, group->l2_flood.group_count);
243
- if (!group->l2_flood.group_ids) {
244
- err = -ROCKER_ENOMEM;
245
- goto err_out;
246
- }
247
248
rocker_tlv_parse_nested(tlvs, group->l2_flood.group_count,
249
group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]);
250
@@ -XXX,XX +XXX,XX @@ static int of_dpa_cmd_group_add(OfDpa *of_dpa, uint32_t group_id,
251
}
252
253
group = of_dpa_group_alloc(group_id);
254
- if (!group) {
255
- return -ROCKER_ENOMEM;
256
- }
257
258
err = of_dpa_cmd_group_do(of_dpa, group_id, group, group_tlvs);
259
if (err) {
260
diff --git a/hw/net/rocker/rocker_world.c b/hw/net/rocker/rocker_world.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/hw/net/rocker/rocker_world.c
263
+++ b/hw/net/rocker/rocker_world.c
264
@@ -XXX,XX +XXX,XX @@ World *world_alloc(Rocker *r, size_t sizeof_private,
265
{
266
World *w = g_malloc0(sizeof(World) + sizeof_private);
267
268
- if (w) {
269
- w->r = r;
270
- w->type = type;
271
- w->ops = ops;
272
- if (w->ops->init) {
273
- w->ops->init(w);
274
- }
275
+ w->r = r;
276
+ w->type = type;
277
+ w->ops = ops;
278
+ if (w->ops->init) {
279
+ w->ops->init(w);
280
}
281
282
return w;
283
--
222
--
284
2.7.4
223
2.7.4
285
286
diff view generated by jsdifflib
Deleted patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
1
3
pci_rocker_init() leaks a World when the name more than 9 chars,
4
then return a negative value directly, doesn't make a correct
5
cleanup. So add a new goto label to fix it.
6
7
Cc: jasowang@redhat.com
8
Cc: jiri@resnulli.us
9
Cc: armbru@redhat.com
10
Cc: f4bug@amsat.org
11
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
12
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
hw/net/rocker/rocker.c | 4 +++-
17
1 file changed, 3 insertions(+), 1 deletion(-)
18
19
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/rocker/rocker.c
22
+++ b/hw/net/rocker/rocker.c
23
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
24
fprintf(stderr,
25
"rocker: name too long; please shorten to at most %d chars\n",
26
MAX_ROCKER_NAME_LEN);
27
- return -EINVAL;
28
+ err = -EINVAL;
29
+ goto err_name_too_long;
30
}
31
32
if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
33
@@ -XXX,XX +XXX,XX @@ static int pci_rocker_init(PCIDevice *dev)
34
35
return 0;
36
37
+err_name_too_long:
38
err_duplicate:
39
rocker_msix_uninit(r);
40
err_msix_init:
41
--
42
2.7.4
43
44
diff view generated by jsdifflib
1
From: Wang Yong <wang.yong155@zte.com.cn>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
Remove the task which check old packet in the comparing thread,
3
It allows using file descriptors of eBPF provided
4
then use IOthread context timer to handle it.
4
outside of QEMU.
5
QEMU may be run without capabilities for eBPF and run
6
RSS program provided by management tool(g.e. libvirt).
5
7
6
Process pactkets in the IOThread which arrived over the socket.
8
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
7
we use iothread_get_g_main_context to create a new g_main_loop in
8
the IOThread.then the packets from the primary and the secondary
9
are processed in the IOThread.
10
11
Finally remove the colo-compare thread using the IOThread instead.
12
13
Reviewed-by: Zhang Chen<zhangchen.fnst@cn.fujitsu.com>
14
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
15
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
10
---
18
net/colo-compare.c | 83 +++++++++++++++++++++++++++++-------------------------
11
ebpf/ebpf_rss-stub.c | 6 ++++++
19
1 file changed, 45 insertions(+), 38 deletions(-)
12
ebpf/ebpf_rss.c | 27 +++++++++++++++++++++++++++
13
ebpf/ebpf_rss.h | 5 +++++
14
3 files changed, 38 insertions(+)
20
15
21
diff --git a/net/colo-compare.c b/net/colo-compare.c
16
diff --git a/ebpf/ebpf_rss-stub.c b/ebpf/ebpf_rss-stub.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/net/colo-compare.c
18
--- a/ebpf/ebpf_rss-stub.c
24
+++ b/net/colo-compare.c
19
+++ b/ebpf/ebpf_rss-stub.c
25
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
26
#include "qemu/sockets.h"
21
return false;
27
#include "qapi-visit.h"
22
}
28
#include "net/colo.h"
23
29
+#include "sysemu/iothread.h"
24
+bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
30
25
+ int config_fd, int toeplitz_fd, int table_fd)
31
#define TYPE_COLO_COMPARE "colo-compare"
26
+{
32
#define COLO_COMPARE(obj) \
27
+ return false;
33
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
34
GQueue conn_list;
35
/* Record the connection without repetition */
36
GHashTable *connection_track_table;
37
- /* This thread just do packet compare job */
38
- QemuThread thread;
39
40
+ IOThread *iothread;
41
GMainContext *worker_context;
42
- GMainLoop *compare_loop;
43
+ QEMUTimer *packet_check_timer;
44
} CompareState;
45
46
typedef struct CompareClass {
47
@@ -XXX,XX +XXX,XX @@ static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
48
* Check old packet regularly so it can watch for any packets
49
* that the secondary hasn't produced equivalents of.
50
*/
51
-static gboolean check_old_packet_regular(void *opaque)
52
+static void check_old_packet_regular(void *opaque)
53
{
54
CompareState *s = opaque;
55
56
/* if have old packet we will notify checkpoint */
57
colo_old_packet_check(s);
58
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
59
+ REGULAR_PACKET_CHECK_MS);
60
+}
28
+}
61
+
29
+
62
+static void colo_compare_timer_init(CompareState *s)
30
bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
31
uint16_t *indirections_table, uint8_t *toeplitz_key)
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)
63
+{
43
+{
64
+ AioContext *ctx = iothread_get_aio_context(s->iothread);
44
+ if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
65
45
+ return false;
66
- return TRUE;
67
+ s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_VIRTUAL,
68
+ SCALE_MS, check_old_packet_regular,
69
+ s);
70
+ timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
71
+ REGULAR_PACKET_CHECK_MS);
72
}
73
74
-static void *colo_compare_thread(void *opaque)
75
+static void colo_compare_timer_del(CompareState *s)
76
{
77
- CompareState *s = opaque;
78
- GSource *timeout_source;
79
+ if (s->packet_check_timer) {
80
+ timer_del(s->packet_check_timer);
81
+ timer_free(s->packet_check_timer);
82
+ s->packet_check_timer = NULL;
83
+ }
84
+ }
85
86
- s->worker_context = g_main_context_new();
87
+static void colo_compare_iothread(CompareState *s)
88
+{
89
+ object_ref(OBJECT(s->iothread));
90
+ s->worker_context = iothread_get_g_main_context(s->iothread);
91
92
qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read,
93
compare_pri_chr_in, NULL, NULL,
94
@@ -XXX,XX +XXX,XX @@ static void *colo_compare_thread(void *opaque)
95
compare_sec_chr_in, NULL, NULL,
96
s, s->worker_context, true);
97
98
- s->compare_loop = g_main_loop_new(s->worker_context, FALSE);
99
-
100
- /* To kick any packets that the secondary doesn't match */
101
- timeout_source = g_timeout_source_new(REGULAR_PACKET_CHECK_MS);
102
- g_source_set_callback(timeout_source,
103
- (GSourceFunc)check_old_packet_regular, s, NULL);
104
- g_source_attach(timeout_source, s->worker_context);
105
-
106
- g_main_loop_run(s->compare_loop);
107
-
108
- g_source_unref(timeout_source);
109
- g_main_loop_unref(s->compare_loop);
110
- g_main_context_unref(s->worker_context);
111
- return NULL;
112
+ colo_compare_timer_init(s);
113
}
114
115
static char *compare_get_pri_indev(Object *obj, Error **errp)
116
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
117
{
118
CompareState *s = COLO_COMPARE(uc);
119
Chardev *chr;
120
- char thread_name[64];
121
- static int compare_id;
122
123
- if (!s->pri_indev || !s->sec_indev || !s->outdev) {
124
+ if (!s->pri_indev || !s->sec_indev || !s->outdev || !s->iothread) {
125
error_setg(errp, "colo compare needs 'primary_in' ,"
126
- "'secondary_in','outdev' property set");
127
+ "'secondary_in','outdev','iothread' property set");
128
return;
129
} else if (!strcmp(s->pri_indev, s->outdev) ||
130
!strcmp(s->sec_indev, s->outdev) ||
131
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
132
g_free,
133
connection_destroy);
134
135
- sprintf(thread_name, "colo-compare %d", compare_id);
136
- qemu_thread_create(&s->thread, thread_name,
137
- colo_compare_thread, s,
138
- QEMU_THREAD_JOINABLE);
139
- compare_id++;
140
-
141
+ colo_compare_iothread(s);
142
return;
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
146
object_property_add_str(obj, "outdev",
147
compare_get_outdev, compare_set_outdev,
148
NULL);
149
+ object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
150
+ (Object **)&s->iothread,
151
+ object_property_allow_set_link,
152
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
153
154
s->vnet_hdr = false;
155
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
156
@@ -XXX,XX +XXX,XX @@ static void colo_compare_finalize(Object *obj)
157
qemu_chr_fe_deinit(&s->chr_pri_in, false);
158
qemu_chr_fe_deinit(&s->chr_sec_in, false);
159
qemu_chr_fe_deinit(&s->chr_out, false);
160
-
161
- g_main_loop_quit(s->compare_loop);
162
- qemu_thread_join(&s->thread);
163
-
164
+ if (s->iothread) {
165
+ colo_compare_timer_del(s);
166
+ }
167
/* Release all unhandled packets after compare thead exited */
168
g_queue_foreach(&s->conn_list, colo_flush_packets, s);
169
170
g_queue_clear(&s->conn_list);
171
172
- g_hash_table_destroy(s->connection_track_table);
173
+ if (s->connection_track_table) {
174
+ g_hash_table_destroy(s->connection_track_table);
175
+ }
46
+ }
176
+
47
+
177
+ if (s->iothread) {
48
+ if (program_fd < 0 || config_fd < 0 || toeplitz_fd < 0 || table_fd < 0) {
178
+ object_unref(OBJECT(s->iothread));
49
+ return false;
179
+ }
50
+ }
180
g_free(s->pri_indev);
51
+
181
g_free(s->sec_indev);
52
+ ctx->program_fd = program_fd;
182
g_free(s->outdev);
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;
66
+}
67
+
68
static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
69
struct EBPFRSSConfig *config)
70
{
71
diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/ebpf/ebpf_rss.h
74
+++ b/ebpf/ebpf_rss.h
75
@@ -XXX,XX +XXX,XX @@
76
#ifndef QEMU_EBPF_RSS_H
77
#define QEMU_EBPF_RSS_H
78
79
+#define EBPF_RSS_MAX_FDS 4
80
+
81
struct EBPFRSSContext {
82
void *obj;
83
int program_fd;
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);
90
+
91
bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
92
uint16_t *indirections_table, uint8_t *toeplitz_key);
93
183
--
94
--
184
2.7.4
95
2.7.4
185
186
diff view generated by jsdifflib
1
From: Wang Yong <wang.yong155@zte.com.cn>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
IOThread uses AioContext event loop and does not run a GMainContext.
3
eBPF RSS program and maps may now be passed during initialization.
4
Therefore,chardev cannot work in IOThread,such as the chardev is
4
Initially was implemented for libvirt to launch qemu without permissions,
5
used for colo-compare packets reception.
5
and initialized eBPF program through the helper.
6
6
7
This patch makes the IOThread run the GMainContext event loop,
7
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
8
chardev and IOThread can work together.
9
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Wang Yong <wang.yong155@zte.com.cn>
12
Signed-off-by: Wang Guang <wang.guang55@zte.com.cn>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
9
---
15
include/sysemu/iothread.h | 4 ++++
10
hw/net/virtio-net.c | 55 +++++++++++++++++++++++++++++++++++++-----
16
iothread.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
11
include/hw/virtio/virtio-net.h | 1 +
17
2 files changed, 49 insertions(+)
12
2 files changed, 50 insertions(+), 6 deletions(-)
18
13
19
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
14
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/include/sysemu/iothread.h
16
--- a/hw/net/virtio-net.c
22
+++ b/include/sysemu/iothread.h
17
+++ b/hw/net/virtio-net.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
18
@@ -XXX,XX +XXX,XX @@
24
19
#include "sysemu/sysemu.h"
25
QemuThread thread;
20
#include "trace.h"
26
AioContext *ctx;
21
#include "monitor/qdev.h"
27
+ GMainContext *worker_context;
22
+#include "monitor/monitor.h"
28
+ GMainLoop *main_loop;
23
#include "hw/pci/pci_device.h"
29
+ GOnce once;
24
#include "net_rx_pkt.h"
30
QemuMutex init_done_lock;
25
#include "hw/virtio/vhost.h"
31
QemuCond init_done_cond; /* is thread initialization done? */
26
@@ -XXX,XX +XXX,XX @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
32
bool stopping;
27
virtio_net_attach_ebpf_to_backend(n->nic, -1);
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
28
}
34
char *iothread_get_id(IOThread *iothread);
29
35
AioContext *iothread_get_aio_context(IOThread *iothread);
30
-static bool virtio_net_load_ebpf(VirtIONet *n)
36
void iothread_stop_all(void);
31
+static bool virtio_net_load_ebpf_fds(VirtIONet *n, Error **errp)
37
+GMainContext *iothread_get_g_main_context(IOThread *iothread);
32
{
38
33
- if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
39
#endif /* IOTHREAD_H */
34
- /* backend does't support steering ebpf */
40
diff --git a/iothread.c b/iothread.c
35
- return false;
41
index XXXXXXX..XXXXXXX 100644
36
+ int fds[EBPF_RSS_MAX_FDS] = { [0 ... EBPF_RSS_MAX_FDS - 1] = -1};
42
--- a/iothread.c
37
+ int nfds = 0;
43
+++ b/iothread.c
38
+ int ret = true;
44
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
39
+ int i = 0;
45
40
+ g_auto(GStrv) fds_strs = g_strsplit(n->ebpf_rss_fds, ":", 0);
46
while (!atomic_read(&iothread->stopping)) {
47
aio_poll(iothread->ctx, true);
48
+
41
+
49
+ if (atomic_read(&iothread->worker_context)) {
42
+ ERRP_GUARD();
50
+ GMainLoop *loop;
51
+
43
+
52
+ g_main_context_push_thread_default(iothread->worker_context);
44
+ if (g_strv_length(fds_strs) != EBPF_RSS_MAX_FDS) {
53
+ iothread->main_loop =
45
+ error_setg(errp,
54
+ g_main_loop_new(iothread->worker_context, TRUE);
46
+ "Expected %d file descriptors but got %d",
55
+ loop = iothread->main_loop;
47
+ EBPF_RSS_MAX_FDS, g_strv_length(fds_strs));
48
+ return false;
49
+ }
56
+
50
+
57
+ g_main_loop_run(iothread->main_loop);
51
+ for (i = 0; i < nfds; i++) {
58
+ iothread->main_loop = NULL;
52
+ fds[i] = monitor_fd_param(monitor_cur(), fds_strs[i], errp);
59
+ g_main_loop_unref(loop);
53
+ if (*errp) {
54
+ ret = false;
55
+ goto exit;
56
+ }
57
+ }
60
+
58
+
61
+ g_main_context_pop_thread_default(iothread->worker_context);
59
+ ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3]);
62
+ g_main_context_unref(iothread->worker_context);
60
+
63
+ iothread->worker_context = NULL;
61
+exit:
62
+ if (!ret || *errp) {
63
+ for (i = 0; i < nfds && fds[i] != -1; i++) {
64
+ close(fds[i]);
64
+ }
65
+ }
65
}
66
}
66
67
67
rcu_unregister_thread();
68
- return ebpf_rss_load(&n->ebpf_rss);
68
@@ -XXX,XX +XXX,XX @@ static int iothread_stop(Object *object, void *opaque)
69
+ return ret;
69
}
70
iothread->stopping = true;
71
aio_notify(iothread->ctx);
72
+ if (atomic_read(&iothread->main_loop)) {
73
+ g_main_loop_quit(iothread->main_loop);
74
+ }
75
qemu_thread_join(&iothread->thread);
76
return 0;
77
}
78
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
79
80
qemu_mutex_init(&iothread->init_done_lock);
81
qemu_cond_init(&iothread->init_done_cond);
82
+ iothread->once = (GOnce) G_ONCE_INIT;
83
84
/* This assumes we are called from a thread with useful CPU affinity for us
85
* to inherit.
86
@@ -XXX,XX +XXX,XX @@ void iothread_stop_all(void)
87
88
object_child_foreach(container, iothread_stop, NULL);
89
}
90
+
91
+static gpointer iothread_g_main_context_init(gpointer opaque)
92
+{
93
+ AioContext *ctx;
94
+ IOThread *iothread = opaque;
95
+ GSource *source;
96
+
97
+ iothread->worker_context = g_main_context_new();
98
+
99
+ ctx = iothread_get_aio_context(iothread);
100
+ source = aio_get_g_source(ctx);
101
+ g_source_attach(source, iothread->worker_context);
102
+ g_source_unref(source);
103
+
104
+ aio_notify(iothread->ctx);
105
+ return NULL;
106
+}
70
+}
107
+
71
+
108
+GMainContext *iothread_get_g_main_context(IOThread *iothread)
72
+static bool virtio_net_load_ebpf(VirtIONet *n, Error **errp)
109
+{
73
+{
110
+ g_once(&iothread->once, iothread_g_main_context_init, iothread);
74
+ bool ret = false;
111
+
75
+
112
+ return iothread->worker_context;
76
+ if (virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
113
+}
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)
87
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
88
net_rx_pkt_init(&n->rx_pkt);
89
90
if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
91
- virtio_net_load_ebpf(n);
92
+ virtio_net_load_ebpf(n, errp);
93
}
94
}
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,
114
--
116
--
115
2.7.4
117
2.7.4
116
117
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
In net_socket_fd_init(), the 'default' case is odd: it warns,
3
Now, the binary objects may be retrieved by id.
4
then continues as if the socket type was SOCK_STREAM. The
4
It would require for future qmp commands that may require specific
5
comment explains "this could be a eg. a pty", but that makes
5
eBPF blob.
6
no sense. If @fd really was a pty, getsockopt() would fail
6
7
with ENOTSOCK. If @fd was a socket, but neither SOCK_DGRAM nor
7
Added command "request-ebpf". This command returns
8
SOCK_STREAM. It should not be treated as if it was SOCK_STREAM.
8
eBPF program encoded base64. The program taken from the
9
9
skeleton and essentially is an ELF object that can be
10
Turn this case into an Error. If there is a genuine reason to
10
loaded in the future with libbpf.
11
support something like SOCK_RAW, it should be explicitly
11
12
handled.
12
The reason to use the command to provide the eBPF object
13
13
instead of a separate artifact was to avoid issues related
14
Cc: jasowang@redhat.com
14
to finding the eBPF itself. eBPF object is an ELF binary
15
Cc: armbru@redhat.com
15
that contains the eBPF program and eBPF map description(BTF).
16
Cc: berrange@redhat.com
16
Overall, eBPF object should contain the program and enough
17
Cc: armbru@redhat.com
17
metadata to create/load eBPF with libbpf. As the eBPF
18
Cc: eblake@redhat.com
18
maps/program should correspond to QEMU, the eBPF can't
19
Suggested-by: Markus Armbruster <armbru@redhat.com>
19
be used from different QEMU build.
20
Suggested-by: Daniel P. Berrange <berrange@redhat.com>
20
21
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
21
The first solution was a helper that comes with QEMU
22
Reviewed-by: Markus Armbruster <armbru@redhat.com>
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>
23
Signed-off-by: Jason Wang <jasowang@redhat.com>
38
Signed-off-by: Jason Wang <jasowang@redhat.com>
24
---
39
---
25
net/socket.c | 6 +++---
40
ebpf/ebpf.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
26
1 file changed, 3 insertions(+), 3 deletions(-)
41
ebpf/ebpf.h | 31 +++++++++++++++++++++++
27
42
ebpf/ebpf_rss.c | 6 +++++
28
diff --git a/net/socket.c b/net/socket.c
43
ebpf/meson.build | 2 +-
29
index XXXXXXX..XXXXXXX 100644
44
qapi/ebpf.json | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
30
--- a/net/socket.c
45
qapi/meson.build | 1 +
31
+++ b/net/socket.c
46
qapi/qapi-schema.json | 1 +
32
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
47
7 files changed, 176 insertions(+), 1 deletion(-)
33
case SOCK_STREAM:
48
create mode 100644 ebpf/ebpf.c
34
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
49
create mode 100644 ebpf/ebpf.h
35
default:
50
create mode 100644 qapi/ebpf.json
36
- /* who knows ... this could be a eg. a pty, do warn and continue as stream */
51
37
- fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
52
diff --git a/ebpf/ebpf.c b/ebpf/ebpf.c
38
- return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
53
new file mode 100644
39
+ error_report("socket type=%d for fd=%d must be either"
54
index XXXXXXX..XXXXXXX
40
+ " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
55
--- /dev/null
41
+ closesocket(fd);
56
+++ b/ebpf/ebpf.c
42
}
57
@@ -XXX,XX +XXX,XX @@
43
return NULL;
58
+/*
59
+ * QEMU eBPF binary declaration routine.
60
+ *
61
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
62
+ *
63
+ * Authors:
64
+ * Andrew Melnychenko <andrew@daynix.com>
65
+ *
66
+ * This work is licensed under the terms of the GNU GPL, version 2 or
67
+ * later. See the COPYING file in the top-level directory.
68
+ */
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;
44
}
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' }
45
--
296
--
46
2.7.4
297
2.7.4
47
48
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
When network is busy, some tcp options(like sack) will unpredictable
3
Updated section name, so libbpf should init/gues proper
4
occur in primary side or secondary side. it will make packet size
4
program type without specifications during open/load.
5
not same, but the two packet's payload is identical. colo just
5
Also, added map_flags with explicitly declared BPF_F_MMAPABLE.
6
care about packet payload, so we skip the option field.
6
Added check for BPF_F_MMAPABLE flag to meson script and
7
requirements to libbpf version.
7
8
8
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
9
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
---
11
net/colo-compare.c | 39 +++++++++++++++++++++++++++------------
12
ebpf/rss.bpf.skeleton.h | 1460 ++++++++++++++++++++++++-----------------------
12
1 file changed, 27 insertions(+), 12 deletions(-)
13
meson.build | 10 +-
14
tools/ebpf/rss.bpf.c | 5 +-
15
3 files changed, 748 insertions(+), 727 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
* return: 0 means packet same
22
20
* > 0 || < 0 means packet different
23
static inline const void *rss_bpf__elf_bytes(size_t *sz)
21
*/
22
-static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
23
+static int colo_packet_compare_common(Packet *ppkt,
24
+ Packet *spkt,
25
+ int poffset,
26
+ int soffset)
27
{
24
{
28
if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
25
-    *sz = 20440;
29
char pri_ip_src[20], pri_ip_dst[20], sec_ip_src[20], sec_ip_dst[20];
26
+    *sz = 20824;
30
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
27
    return (const void *)"\
31
sec_ip_src, sec_ip_dst);
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\
32
}
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\
33
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\
34
- offset = ppkt->vnet_hdr_len + offset;
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\
35
+ poffset = ppkt->vnet_hdr_len + poffset;
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\
36
+ soffset = ppkt->vnet_hdr_len + soffset;
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\
37
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\
38
- if (ppkt->size == spkt->size) {
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\
39
- return memcmp(ppkt->data + offset,
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\
40
- spkt->data + offset,
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\
41
- spkt->size - offset);
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\
42
+ if (ppkt->size - poffset == spkt->size - soffset) {
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\
43
+ return memcmp(ppkt->data + poffset,
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\
44
+ spkt->data + soffset,
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\
45
+ spkt->size - soffset);
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\
46
} else {
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\
47
trace_colo_compare_main("Net packet size are not the same");
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\
48
return -1;
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\
49
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
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\
50
* so we just need skip this field.
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\
51
*/
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\
52
if (ptcp->th_off > 5) {
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\
53
- ptrdiff_t tcp_offset;
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\
54
+ ptrdiff_t ptcp_offset, stcp_offset;
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\
55
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\
56
- tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
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\
57
- + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
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\
58
- res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
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\
59
+ ptcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
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\
60
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
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\
61
+ stcp_offset = spkt->transport_header - (uint8_t *)spkt->data
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\
62
+ + (stcp->th_off * 4) - spkt->vnet_hdr_len;
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\
63
+
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\
64
+ /*
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\
65
+ * When network is busy, some tcp options(like sack) will unpredictable
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\
66
+ * occur in primary side or secondary side. it will make packet size
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\
67
+ * not same, but the two packet's payload is identical. colo just
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\
68
+ * care about packet payload, so we skip the option field.
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\
69
+ */
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\
70
+ res = colo_packet_compare_common(ppkt, spkt, ptcp_offset, stcp_offset);
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\
71
} else if (ptcp->th_sum == stcp->th_sum) {
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\
72
- res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
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\
73
+ res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN, ETH_HLEN);
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\
74
} else {
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\
75
res = -1;
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\
76
}
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\
77
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_udp(Packet *spkt, Packet *ppkt)
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\
78
* the ip payload here.
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\
79
*/
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\
80
ret = colo_packet_compare_common(ppkt, spkt,
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\
81
+ network_header_length + ETH_HLEN,
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\
82
network_header_length + ETH_HLEN);
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\
83
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\
84
if (ret) {
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\
85
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)
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\
86
* the ip payload here.
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\
87
*/
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\
88
if (colo_packet_compare_common(ppkt, spkt,
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\
89
+ network_header_length + ETH_HLEN,
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\
90
network_header_length + ETH_HLEN)) {
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\
91
trace_colo_compare_icmp_miscompare("primary pkt size",
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\
92
ppkt->size);
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\
93
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_other(Packet *spkt, Packet *ppkt)
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\
94
sec_ip_src, sec_ip_dst);
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\
95
}
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\
96
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\
97
- return colo_packet_compare_common(ppkt, spkt, 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\
98
+ return colo_packet_compare_common(ppkt, spkt, 0, 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";
99
}
1538
}
100
1539
101
static int colo_old_packet_check_one(Packet *pkt, int64_t *check_time)
1540
#ifdef __cplusplus
1541
diff --git a/meson.build b/meson.build
1542
index XXXXXXX..XXXXXXX 100644
1543
--- a/meson.build
1544
+++ b/meson.build
1545
@@ -XXX,XX +XXX,XX @@ elif get_option('vduse_blk_export').disabled()
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;
1602
}
1603
1604
-SEC("tun_rss_steering")
1605
+SEC("socket")
1606
int tun_rss_steering_prog(struct __sk_buff *skb)
1607
{
1608
102
--
1609
--
103
2.7.4
1610
2.7.4
104
105
diff view generated by jsdifflib