/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/* This sequence number should be incremented whenever anything involving flows
* or the wildcarding of flows changes. This will cause build assertion
* failures in places which likely need to be updated. */
-#define FLOW_WC_SEQ 18
+#define FLOW_WC_SEQ 20
#define FLOW_N_REGS 8
BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
uint8_t ip_ttl;
};
+/* Unfortunately, a "struct flow" sometimes has to handle OpenFlow port
+ * numbers and other times datapath (dpif) port numbers. This union allows
+ * access to both. */
+union flow_in_port {
+ ofp_port_t ofp_port;
+ odp_port_t odp_port;
+};
+
/*
* A flow in the network.
*
ovs_be32 nw_src; /* IPv4 source address. */
ovs_be32 nw_dst; /* IPv4 destination address. */
ovs_be32 ipv6_label; /* IPv6 flow label. */
- uint32_t in_port; /* Input port. OpenFlow port number
- unless in DPIF code, in which case it
- is the datapath port number. */
- uint32_t skb_mark; /* Packet mark. */
+ union flow_in_port in_port; /* Input port.*/
+ uint32_t pkt_mark; /* Packet mark. */
+ ovs_be32 mpls_lse; /* MPLS label stack entry. */
+ uint16_t mpls_depth; /* Depth of MPLS stack. */
ovs_be16 vlan_tci; /* If 802.1Q, TCI | VLAN_CFI; otherwise 0. */
ovs_be16 dl_type; /* Ethernet frame type. */
ovs_be16 tp_src; /* TCP/UDP source port. */
uint8_t arp_tha[6]; /* ARP/ND target hardware address. */
uint8_t nw_ttl; /* IP TTL/Hop Limit. */
uint8_t nw_frag; /* FLOW_FRAG_* flags. */
- uint8_t zeros[4];
+ uint8_t zeros[6];
};
BUILD_ASSERT_DECL(sizeof(struct flow) % 4 == 0);
#define FLOW_U32S (sizeof(struct flow) / 4)
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
-BUILD_ASSERT_DECL(sizeof(struct flow) == sizeof(struct flow_tnl) + 152 &&
- FLOW_WC_SEQ == 18);
+BUILD_ASSERT_DECL(sizeof(struct flow) == sizeof(struct flow_tnl) + 160 &&
+ FLOW_WC_SEQ == 20);
/* Represents the metadata fields of struct flow. */
struct flow_metadata {
ovs_be64 tun_id; /* Encapsulating tunnel ID. */
+ ovs_be32 tun_src; /* Tunnel outer IPv4 src addr */
+ ovs_be32 tun_dst; /* Tunnel outer IPv4 dst addr */
ovs_be64 metadata; /* OpenFlow 1.1+ metadata field. */
uint32_t regs[FLOW_N_REGS]; /* Registers. */
- uint16_t in_port; /* OpenFlow port or zero. */
+ uint32_t pkt_mark; /* Packet mark. */
+ ofp_port_t in_port; /* OpenFlow port or zero. */
};
void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
- const struct flow_tnl *, uint16_t in_port, struct flow *);
-void flow_extract_l3_onwards(struct ofpbuf *, struct flow *,
- ovs_be16 dl_type);
+ const struct flow_tnl *, const union flow_in_port *in_port,
+ struct flow *);
+
void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
void flow_get_metadata(const struct flow *, struct flow_metadata *);
void flow_set_vlan_vid(struct flow *, ovs_be16 vid);
void flow_set_vlan_pcp(struct flow *, uint8_t pcp);
+void flow_set_mpls_label(struct flow *flow, ovs_be32 label);
+void flow_set_mpls_ttl(struct flow *flow, uint8_t ttl);
+void flow_set_mpls_tc(struct flow *flow, uint8_t tc);
+void flow_set_mpls_bos(struct flow *flow, uint8_t stack);
+
void flow_compose(struct ofpbuf *, const struct flow *);
static inline int
return hash_words((const uint32_t *) flow, sizeof *flow / 4, basis);
}
+static inline uint16_t
+ofp_to_u16(ofp_port_t ofp_port)
+{
+ return (OVS_FORCE uint16_t) ofp_port;
+}
+
+static inline uint32_t
+odp_to_u32(odp_port_t odp_port)
+{
+ return (OVS_FORCE uint32_t) odp_port;
+}
+
+static inline uint32_t
+ofp11_to_u32(ofp11_port_t ofp11_port)
+{
+ return (OVS_FORCE uint32_t) ofp11_port;
+}
+
+static inline ofp_port_t
+u16_to_ofp(uint16_t port)
+{
+ return OFP_PORT_C(port);
+}
+
+static inline odp_port_t
+u32_to_odp(uint32_t port)
+{
+ return ODP_PORT_C(port);
+}
+
+static inline ofp11_port_t
+u32_to_ofp11(uint32_t port)
+{
+ return OFP11_PORT_C(port);
+}
+
+static inline uint32_t
+hash_ofp_port(ofp_port_t ofp_port)
+{
+ return hash_int(ofp_to_u16(ofp_port), 0);
+}
+
+static inline uint32_t
+hash_odp_port(odp_port_t odp_port)
+{
+ return hash_int(odp_to_u32(odp_port), 0);
+}
+
uint32_t flow_hash_in_minimask(const struct flow *, const struct minimask *,
uint32_t basis);
\f
void flow_wildcards_set_reg_mask(struct flow_wildcards *,
int idx, uint32_t mask);
-void flow_wildcards_combine(struct flow_wildcards *dst,
- const struct flow_wildcards *src1,
- const struct flow_wildcards *src2);
+void flow_wildcards_and(struct flow_wildcards *dst,
+ const struct flow_wildcards *src1,
+ const struct flow_wildcards *src2);
+void flow_wildcards_or(struct flow_wildcards *dst,
+ const struct flow_wildcards *src1,
+ const struct flow_wildcards *src2);
bool flow_wildcards_has_extra(const struct flow_wildcards *,
const struct flow_wildcards *);
+void flow_wildcards_fold_minimask(struct flow_wildcards *,
+ const struct minimask *);
+
uint32_t flow_wildcards_hash(const struct flow_wildcards *, uint32_t basis);
bool flow_wildcards_equal(const struct flow_wildcards *,
const struct flow_wildcards *);
uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis);
+void flow_mask_hash_fields(const struct flow *, struct flow_wildcards *,
+ enum nx_hash_fields);
uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields,
uint16_t basis);
const char *flow_hash_fields_to_str(enum nx_hash_fields);
bool flow_hash_fields_valid(enum nx_hash_fields);
+uint32_t flow_hash_in_wildcards(const struct flow *,
+ const struct flow_wildcards *,
+ uint32_t basis);
+
bool flow_equal_except(const struct flow *a, const struct flow *b,
const struct flow_wildcards *);
\f