2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-13 14:07:02 +00:00
Files
openvswitch/lib/match.h

205 lines
9.5 KiB
C
Raw Normal View History

/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 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.
*/
#ifndef MATCH_H
#define MATCH_H 1
#include "flow.h"
#include "packets.h"
tunnel: Geneve TLV handling support for OpenFlow. The current support for Geneve in OVS is exactly equivalent to VXLAN: it is possible to set and match on the VNI but not on any options contained in the header. This patch enables the use of options. The goal for Geneve support is not to add support for any particular option but to allow end users or controllers to specify what they would like to match. That is, the full range of Geneve's capabilities should be exposed without modifying the code (the one exception being options that require per-packet computation in the fast path). The main issue with supporting Geneve options is how to integrate the fields into the existing OpenFlow pipeline. All existing operations are referred to by their NXM/OXM field name - matches, action generation, arithmetic operations (i.e. tranfer to a register). However, the Geneve option space is exactly the same as the OXM space, so a direct mapping is not feasible. Instead, we create a pool of 64 NXMs that are then dynamically mapped on Geneve option TLVs using OpenFlow. Once mapped, these fields become first-class citizens in the OpenFlow pipeline. An example of how to use Geneve options: ovs-ofctl add-geneve-map br0 {class=0xffff,type=0,len=4}->tun_metadata0 ovs-ofctl add-flow br0 in_port=LOCAL,actions=set_field:0xffffffff->tun_metadata0,1 This will add a 4 bytes option (filled will all 1's) to all packets coming from the LOCAL port and then send then out to port 1. A limitation of this patch is that although the option table is specified for a particular switch over OpenFlow, it is currently global to all switches. This will be addressed in a future patch. Based on work originally done by Madhu Challa. Ben Pfaff also significantly improved the comments. Signed-off-by: Madhu Challa <challa@noironetworks.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2015-04-30 18:09:57 -07:00
#include "tun-metadata.h"
struct ds;
/* A flow classification match.
*
* Use one of the match_*() functions to initialize a "struct match".
*
* The match_*() functions below maintain the following important invariant.
* If a bit or a field is wildcarded in 'wc', then the corresponding bit or
* field in 'flow' is set to all-0-bits. (The match_zero_wildcarded_fields()
* function can be used to restore this invariant after adding wildcards.) */
struct match {
struct flow flow;
struct flow_wildcards wc;
tunnel: Geneve TLV handling support for OpenFlow. The current support for Geneve in OVS is exactly equivalent to VXLAN: it is possible to set and match on the VNI but not on any options contained in the header. This patch enables the use of options. The goal for Geneve support is not to add support for any particular option but to allow end users or controllers to specify what they would like to match. That is, the full range of Geneve's capabilities should be exposed without modifying the code (the one exception being options that require per-packet computation in the fast path). The main issue with supporting Geneve options is how to integrate the fields into the existing OpenFlow pipeline. All existing operations are referred to by their NXM/OXM field name - matches, action generation, arithmetic operations (i.e. tranfer to a register). However, the Geneve option space is exactly the same as the OXM space, so a direct mapping is not feasible. Instead, we create a pool of 64 NXMs that are then dynamically mapped on Geneve option TLVs using OpenFlow. Once mapped, these fields become first-class citizens in the OpenFlow pipeline. An example of how to use Geneve options: ovs-ofctl add-geneve-map br0 {class=0xffff,type=0,len=4}->tun_metadata0 ovs-ofctl add-flow br0 in_port=LOCAL,actions=set_field:0xffffffff->tun_metadata0,1 This will add a 4 bytes option (filled will all 1's) to all packets coming from the LOCAL port and then send then out to port 1. A limitation of this patch is that although the option table is specified for a particular switch over OpenFlow, it is currently global to all switches. This will be addressed in a future patch. Based on work originally done by Madhu Challa. Ben Pfaff also significantly improved the comments. Signed-off-by: Madhu Challa <challa@noironetworks.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2015-04-30 18:09:57 -07:00
struct tun_metadata_allocation tun_md;
};
/* Initializer for a "struct match" that matches every packet. */
#define MATCH_CATCHALL_INITIALIZER { .flow = { .dl_type = 0 } }
void match_init(struct match *,
const struct flow *, const struct flow_wildcards *);
void match_wc_init(struct match *match, const struct flow *flow);
void match_init_catchall(struct match *);
void match_zero_wildcarded_fields(struct match *);
void match_set_dp_hash(struct match *, uint32_t value);
void match_set_dp_hash_masked(struct match *, uint32_t value, uint32_t mask);
void match_set_recirc_id(struct match *, uint32_t value);
void match_set_conj_id(struct match *, uint32_t value);
void match_set_reg(struct match *, unsigned int reg_idx, uint32_t value);
void match_set_reg_masked(struct match *, unsigned int reg_idx,
uint32_t value, uint32_t mask);
void match_set_xreg(struct match *, unsigned int xreg_idx, uint64_t value);
void match_set_xreg_masked(struct match *, unsigned int xreg_idx,
uint64_t value, uint64_t mask);
void match_set_actset_output(struct match *, ofp_port_t actset_output);
void match_set_metadata(struct match *, ovs_be64 metadata);
void match_set_metadata_masked(struct match *,
ovs_be64 metadata, ovs_be64 mask);
void match_set_tun_id(struct match *, ovs_be64 tun_id);
void match_set_tun_id_masked(struct match *, ovs_be64 tun_id, ovs_be64 mask);
void match_set_tun_src(struct match *match, ovs_be32 src);
void match_set_tun_src_masked(struct match *match, ovs_be32 src, ovs_be32 mask);
void match_set_tun_dst(struct match *match, ovs_be32 dst);
void match_set_tun_dst_masked(struct match *match, ovs_be32 dst, ovs_be32 mask);
void match_set_tun_ttl(struct match *match, uint8_t ttl);
void match_set_tun_ttl_masked(struct match *match, uint8_t ttl, uint8_t mask);
void match_set_tun_tos(struct match *match, uint8_t tos);
void match_set_tun_tos_masked(struct match *match, uint8_t tos, uint8_t mask);
void match_set_tun_flags(struct match *match, uint16_t flags);
void match_set_tun_flags_masked(struct match *match, uint16_t flags, uint16_t mask);
void match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16 mask);
void match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id);
void match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
void match_set_tun_gbp_flags(struct match *match, uint8_t flags);
void match_set_in_port(struct match *, ofp_port_t ofp_port);
void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask);
Add support for connection tracking. This patch adds a new action and fields to OVS that allow connection tracking to be performed. This support works in conjunction with the Linux kernel support merged into the Linux-4.3 development cycle. Packets have two possible states with respect to connection tracking: Untracked packets have not previously passed through the connection tracker, while tracked packets have previously been through the connection tracker. For OpenFlow pipeline processing, untracked packets can become tracked, and they will remain tracked until the end of the pipeline. Tracked packets cannot become untracked. Connections can be unknown, uncommitted, or committed. Packets which are untracked have unknown connection state. To know the connection state, the packet must become tracked. Uncommitted connections have no connection state stored about them, so it is only possible for the connection tracker to identify whether they are a new connection or whether they are invalid. Committed connections have connection state stored beyond the lifetime of the packet, which allows later packets in the same connection to be identified as part of the same established connection, or related to an existing connection - for instance ICMP error responses. The new 'ct' action transitions the packet from "untracked" to "tracked" by sending this flow through the connection tracker. The following parameters are supported initally: - "commit": When commit is executed, the connection moves from uncommitted state to committed state. This signals that information about the connection should be stored beyond the lifetime of the packet within the pipeline. This allows future packets in the same connection to be recognized as part of the same "established" (est) connection, as well as identifying packets in the reply (rpl) direction, or packets related to an existing connection (rel). - "zone=[u16|NXM]": Perform connection tracking in the zone specified. Each zone is an independent connection tracking context. When the "commit" parameter is used, the connection will only be committed in the specified zone, and not in other zones. This is 0 by default. - "table=NUMBER": Fork pipeline processing in two. The original instance of the packet will continue processing the current actions list as an untracked packet. An additional instance of the packet will be sent to the connection tracker, which will be re-injected into the OpenFlow pipeline to resume processing in the specified table, with the ct_state and other ct match fields set. If the table is not specified, then the packet is submitted to the connection tracker, but the pipeline does not fork and the ct match fields are not populated. It is strongly recommended to specify a table later than the current table to prevent loops. When the "table" option is used, the packet that continues processing in the specified table will have the ct_state populated. The ct_state may have any of the following flags set: - Tracked (trk): Connection tracking has occurred. - Reply (rpl): The flow is in the reply direction. - Invalid (inv): The connection tracker couldn't identify the connection. - New (new): This is the beginning of a new connection. - Established (est): This is part of an already existing connection. - Related (rel): This connection is related to an existing connection. For more information, consult the ovs-ofctl(8) man pages. Below is a simple example flow table to allow outbound TCP traffic from port 1 and drop traffic from port 2 that was not initiated by port 1: table=0,priority=1,action=drop table=0,arp,action=normal table=0,in_port=1,tcp,ct_state=-trk,action=ct(commit,zone=9),2 table=0,in_port=2,tcp,ct_state=-trk,action=ct(zone=9,table=1) table=1,in_port=2,ct_state=+trk+est,tcp,action=1 table=1,in_port=2,ct_state=+trk+new,tcp,action=drop Based on original design by Justin Pettit, contributions from Thomas Graf and Daniele Di Proietto. Signed-off-by: Joe Stringer <joestringer@nicira.com> Acked-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2015-08-11 10:56:09 -07:00
void match_set_ct_state(struct match *, uint32_t ct_state);
void match_set_ct_state_masked(struct match *, uint32_t ct_state, uint32_t mask);
void match_set_ct_zone(struct match *, uint16_t ct_zone);
void match_set_ct_mark(struct match *, uint32_t ct_mark);
void match_set_ct_mark_masked(struct match *, uint32_t ct_mark, uint32_t mask);
void match_set_skb_priority(struct match *, uint32_t skb_priority);
void match_set_dl_type(struct match *, ovs_be16);
void match_set_dl_src(struct match *, const struct eth_addr );
void match_set_dl_src_masked(struct match *, const struct eth_addr dl_src,
const struct eth_addr mask);
void match_set_dl_dst(struct match *, const struct eth_addr);
void match_set_dl_dst_masked(struct match *, const struct eth_addr dl_dst,
const struct eth_addr mask);
void match_set_dl_tci(struct match *, ovs_be16 tci);
void match_set_dl_tci_masked(struct match *, ovs_be16 tci, ovs_be16 mask);
void match_set_any_vid(struct match *);
void match_set_dl_vlan(struct match *, ovs_be16);
void match_set_vlan_vid(struct match *, ovs_be16);
void match_set_vlan_vid_masked(struct match *, ovs_be16 vid, ovs_be16 mask);
void match_set_any_pcp(struct match *);
void match_set_dl_vlan_pcp(struct match *, uint8_t);
void match_set_any_mpls_lse(struct match *, int idx);
void match_set_mpls_lse(struct match *, int idx, ovs_be32);
void match_set_any_mpls_label(struct match *, int idx);
void match_set_mpls_label(struct match *, int idx, ovs_be32);
void match_set_any_mpls_tc(struct match *, int idx);
void match_set_mpls_tc(struct match *, int idx, uint8_t);
void match_set_any_mpls_bos(struct match *, int idx);
void match_set_mpls_bos(struct match *, int idx, uint8_t);
void match_set_tp_src(struct match *, ovs_be16);
void match_set_mpls_lse(struct match *, int idx, ovs_be32 lse);
void match_set_tp_src_masked(struct match *, ovs_be16 port, ovs_be16 mask);
void match_set_tp_dst(struct match *, ovs_be16);
void match_set_tp_dst_masked(struct match *, ovs_be16 port, ovs_be16 mask);
void match_set_tcp_flags(struct match *, ovs_be16);
void match_set_tcp_flags_masked(struct match *, ovs_be16 flags, ovs_be16 mask);
void match_set_nw_proto(struct match *, uint8_t);
void match_set_nw_src(struct match *, ovs_be32);
void match_set_nw_src_masked(struct match *, ovs_be32 ip, ovs_be32 mask);
void match_set_nw_dst(struct match *, ovs_be32);
void match_set_nw_dst_masked(struct match *, ovs_be32 ip, ovs_be32 mask);
void match_set_nw_dscp(struct match *, uint8_t);
void match_set_nw_ecn(struct match *, uint8_t);
void match_set_nw_ttl(struct match *, uint8_t);
void match_set_nw_frag(struct match *, uint8_t nw_frag);
void match_set_nw_frag_masked(struct match *, uint8_t nw_frag, uint8_t mask);
void match_set_icmp_type(struct match *, uint8_t);
void match_set_icmp_code(struct match *, uint8_t);
void match_set_arp_sha(struct match *, const struct eth_addr);
void match_set_arp_sha_masked(struct match *,
const struct eth_addr arp_sha,
const struct eth_addr mask);
void match_set_arp_tha(struct match *, const struct eth_addr);
void match_set_arp_tha_masked(struct match *,
const struct eth_addr arp_tha,
const struct eth_addr mask);
void match_set_ipv6_src(struct match *, const struct in6_addr *);
void match_set_ipv6_src_masked(struct match *, const struct in6_addr *,
const struct in6_addr *);
void match_set_ipv6_dst(struct match *, const struct in6_addr *);
void match_set_ipv6_dst_masked(struct match *, const struct in6_addr *,
const struct in6_addr *);
void match_set_ipv6_label(struct match *, ovs_be32);
void match_set_ipv6_label_masked(struct match *, ovs_be32, ovs_be32);
void match_set_nd_target(struct match *, const struct in6_addr *);
void match_set_nd_target_masked(struct match *, const struct in6_addr *,
const struct in6_addr *);
bool match_equal(const struct match *, const struct match *);
uint32_t match_hash(const struct match *, uint32_t basis);
void match_init_hidden_fields(struct match *);
bool match_has_default_hidden_fields(const struct match *);
void match_format(const struct match *, struct ds *, int priority);
char *match_to_string(const struct match *, int priority);
void match_print(const struct match *);
/* Compressed match. */
/* A sparse representation of a "struct match".
*
* 'flows' is used for allocating both 'flow' and 'mask' with one
* miniflow_alloc() call.
*
* There are two invariants:
*
* - The same invariant as "struct match", that is, a 1-bit in the 'flow'
* must correspond to a 1-bit in 'mask'.
*
* - 'flow' and 'mask' have the same 'map'. This implies that 'flow' and
* 'mask' have the same part of "struct flow" at the same offset into
* 'values', which makes minimatch_matches_flow() faster.
*/
struct minimatch {
union {
struct {
struct miniflow *flow;
struct minimask *mask;
};
struct miniflow *flows[2];
};
};
void minimatch_init(struct minimatch *, const struct match *);
void minimatch_clone(struct minimatch *, const struct minimatch *);
void minimatch_move(struct minimatch *dst, struct minimatch *src);
void minimatch_destroy(struct minimatch *);
void minimatch_expand(const struct minimatch *, struct match *);
bool minimatch_equal(const struct minimatch *a, const struct minimatch *b);
bool minimatch_matches_flow(const struct minimatch *, const struct flow *);
void minimatch_format(const struct minimatch *, struct ds *, int priority);
char *minimatch_to_string(const struct minimatch *, int priority);
#endif /* match.h */