@@ -126,10 +126,13 @@ static int packet_enqueue(CompareState *s, int mode)
pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
}
- if (parse_packet_early(pkt)) {
- packet_destroy(pkt, NULL);
- pkt = NULL;
- return -1;
+ /* Try to parse the virtio-net-pci packet */
+ if (parse_packet_early(pkt, VIRTIO_NET_HEADER)) {
+ if (parse_packet_early(pkt, 0)) {
+ packet_destroy(pkt, NULL);
+ pkt = NULL;
+ return -1;
+ }
}
fill_connection_key(pkt, &key);
@@ -39,15 +39,15 @@ int connection_key_equal(const void *key1, const void *key2)
return memcmp(key1, key2, sizeof(ConnectionKey)) == 0;
}
-int parse_packet_early(Packet *pkt)
+int parse_packet_early(Packet *pkt, int offset)
{
int network_length;
static const uint8_t vlan[] = {0x81, 0x00};
- uint8_t *data = pkt->data;
+ uint8_t *data = pkt->data + offset;
uint16_t l3_proto;
ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
- if (pkt->size < ETH_HLEN) {
+ if (pkt->size < ETH_HLEN + offset) {
trace_colo_proxy_main("pkt->size < ETH_HLEN");
return 1;
}
@@ -73,7 +73,7 @@ int parse_packet_early(Packet *pkt)
}
network_length = pkt->ip->ip_hl * 4;
- if (pkt->size < l2hdr_len + network_length) {
+ if (pkt->size < l2hdr_len + network_length + offset) {
trace_colo_proxy_main("pkt->size < network_header + network_length");
return 1;
}
@@ -33,6 +33,9 @@
#define IPPROTO_UDPLITE 136
#endif
+/* virtio-net header length */
+#define VIRTIO_NET_HEADER 12
+
typedef struct Packet {
void *data;
union {
@@ -73,7 +76,7 @@ typedef struct Connection {
uint32_t connection_key_hash(const void *opaque);
int connection_key_equal(const void *opaque1, const void *opaque2);
-int parse_packet_early(Packet *pkt);
+int parse_packet_early(Packet *pkt, int offset);
void fill_connection_key(Packet *pkt, ConnectionKey *key);
void reverse_connection_key(ConnectionKey *key);
Connection *connection_new(ConnectionKey *key);
@@ -51,12 +51,17 @@ static void filter_rewriter_flush(NetFilterState *nf)
*/
static int is_tcp_packet(Packet *pkt)
{
- if (!parse_packet_early(pkt) &&
- pkt->ip->ip_p == IPPROTO_TCP) {
- return 1;
- } else {
- return 0;
+ if (!parse_packet_early(pkt, VIRTIO_NET_HEADER) ||
+ !parse_packet_early(pkt, 0)) {
+ if (pkt->ip->ip_p == IPPROTO_TCP) {
+ return 1;
+ } else {
+ goto out;
+ }
}
+
+out:
+ return 0;
}
/* handle tcp packet from primary guest */
Change parse_packet_early(Packet *pkt) to parse_packet_early(Packet *pkt, int offset) that we can skip virtio-net header. Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com> --- net/colo-compare.c | 11 +++++++---- net/colo.c | 8 ++++---- net/colo.h | 5 ++++- net/filter-rewriter.c | 15 ++++++++++----- 4 files changed, 25 insertions(+), 14 deletions(-)