2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 09:58:01 +00:00
ovs/tests/test-flows.c

102 lines
3.3 KiB
C
Raw Normal View History

/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <config.h>
#undef NDEBUG
#include "flow.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "classifier.h"
#include "openflow/openflow.h"
#include "openvswitch/ofp-match.h"
#include "openvswitch/ofp-print.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/vlog.h"
#include "ovstest.h"
#include "dp-packet.h"
#include "pcap-file.h"
#include "timeval.h"
#include "util.h"
static void
test_flows_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
{
struct ofp10_match expected_match;
FILE *flows;
struct pcap_file *pcap;
int retval;
int n = 0, errors = 0;
set_program_name(argv[0]);
flows = fopen(argv[1], "rb");
if (!flows) {
ovs_fatal(errno, "failed to open %s", argv[1]);
}
pcap = ovs_pcap_open(argv[2], "rb");
if (!pcap) {
ovs_fatal(errno, "failed to open %s", argv[2]);
}
while (fread(&expected_match, sizeof expected_match, 1, flows)) {
struct dp_packet *packet;
struct ofp10_match extracted_match;
struct match match;
struct flow flow;
n++;
retval = ovs_pcap_read(pcap, &packet, NULL);
if (retval == EOF) {
ovs_fatal(0, "unexpected end of file reading pcap file");
} else if (retval) {
ovs_fatal(retval, "error reading pcap file");
}
flow_extract(packet, &flow);
flow.in_port.ofp_port = u16_to_ofp(1);
match_wc_init(&match, &flow);
ofputil_match_to_ofp10_match(&match, &extracted_match);
if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) {
char *exp_s = ofp10_match_to_string(&expected_match, NULL, 2);
char *got_s = ofp10_match_to_string(&extracted_match, NULL, 2);
errors++;
printf("mismatch on packet #%d (1-based).\n", n);
printf("Packet:\n");
userspace: Add packet_type in dp_packet and flow This commit adds a packet_type attribute to the structs dp_packet and flow to explicitly carry the type of the packet as prepration for the introduction of the so-called packet type-aware pipeline (PTAP) in OVS. The packet_type is a big-endian 32 bit integer with the encoding as specified in OpenFlow verion 1.5. The upper 16 bits contain the packet type name space. Pre-defined values are defined in openflow-common.h: enum ofp_header_type_namespaces { OFPHTN_ONF = 0, /* ONF namespace. */ OFPHTN_ETHERTYPE = 1, /* ns_type is an Ethertype. */ OFPHTN_IP_PROTO = 2, /* ns_type is a IP protocol number. */ OFPHTN_UDP_TCP_PORT = 3, /* ns_type is a TCP or UDP port. */ OFPHTN_IPV4_OPTION = 4, /* ns_type is an IPv4 option number. */ }; The lower 16 bits specify the actual type in the context of the name space. Only name spaces 0 and 1 will be supported for now. For name space OFPHTN_ONF the relevant packet type is 0 (Ethernet). This is the default packet_type in OVS and the only one supported so far. Packets of type (OFPHTN_ONF, 0) are called Ethernet packets. In name space OFPHTN_ETHERTYPE the type is the Ethertype of the packet. A packet of type (OFPHTN_ETHERTYPE, <Ethertype>) is a standard L2 packet whith the Ethernet header (and any VLAN tags) removed to expose the L3 (or L2.5) payload of the packet. These will simply be called L3 packets. The Ethernet address fields dl_src and dl_dst in struct flow are not applicable for an L3 packet and must be zero. However, to maintain compatibility with the large code base, we have chosen to copy the Ethertype of an L3 packet into the the dl_type field of struct flow. This does not mean that it will be possible to match on dl_type for L3 packets with PTAP later on. Matching must be done on packet_type instead. New dp_packets are initialized with packet_type Ethernet. Ports that receive L3 packets will have to explicitly adjust the packet_type. Signed-off-by: Jean Tourrilhes <jt@labs.hpe.com> Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com> Co-authored-by: Zoltan Balogh <zoltan.balogh@ericsson.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
2017-04-25 16:29:59 +00:00
ofp_print_packet(stdout, dp_packet_data(packet), dp_packet_size(packet), htonl(PT_ETH));
ovs_hex_dump(stdout, dp_packet_data(packet), dp_packet_size(packet), 0, true);
match_print(&match, NULL);
printf("Expected flow:\n%s\n", exp_s);
printf("Actually extracted flow:\n%s\n", got_s);
Implement new fragment handling policy. Until now, OVS has handled IP fragments more awkwardly than necessary. It has not been possible to match on L4 headers, even in fragments with offset 0 where they are actually present. This means that there was no way to implement ACLs that treat, say, different TCP ports differently, on fragmented traffic; instead, all decisions for fragment forwarding had to be made on the basis of L2 and L3 headers alone. This commit improves the situation significantly. It is still not possible to match on L4 headers in fragments with nonzero offset, because that information is simply not present in such fragments, but this commit adds the ability to match on L4 headers for fragments with zero offset. This means that it becomes possible to implement ACLs that drop such "first fragments" on the basis of L4 headers. In practice, that effectively blocks even fragmented traffic on an L4 basis, because the receiving IP stack cannot reassemble a full packet when the first fragment is missing. This commit works by adding a new "fragment type" to the kernel flow match and making it available through OpenFlow as a new NXM field named NXM_NX_IP_FRAG. Because OpenFlow 1.0 explicitly says that the L4 fields are always 0 for IP fragments, it adds a new OpenFlow fragment handling mode that fills in the L4 fields for "first fragments". It also enhances ovs-ofctl to allow users to configure this new fragment handling mode and to parse the new field. Signed-off-by: Ben Pfaff <blp@nicira.com> Bug #7557.
2011-10-19 21:33:44 -07:00
ovs_hex_dump(stdout, &expected_match, sizeof expected_match, 0, false);
ovs_hex_dump(stdout, &extracted_match, sizeof extracted_match, 0, false);
printf("\n");
free(exp_s);
free(got_s);
}
dp_packet_delete(packet);
}
ovs_pcap_close(pcap);
printf("checked %d packets, %d errors\n", n, errors);
exit(errors != 0);
}
OVSTEST_REGISTER("test-flows", test_flows_main);