#include "openvswitch/dynamic-string.h"
#include "hash.h"
#include "jhash.h"
-#include "match.h"
+#include "openvswitch/match.h"
#include "dp-packet.h"
#include "openflow/openflow.h"
#include "packets.h"
miniflow_push_uint32(mf, ct_mark, md->ct_mark);
miniflow_pad_to_64(mf, ct_mark);
- if (!ovs_u128_is_zero(&md->ct_label)) {
+ if (!ovs_u128_is_zero(md->ct_label)) {
miniflow_push_words(mf, ct_label, &md->ct_label,
sizeof md->ct_label / sizeof(uint64_t));
}
if (flow->ct_mark != 0) {
match_set_ct_mark(flow_metadata, flow->ct_mark);
}
- if (!ovs_u128_is_zero(&flow->ct_label)) {
+ if (!ovs_u128_is_zero(flow->ct_label)) {
match_set_ct_label(flow_metadata, flow->ct_label);
}
}
if (!flow->ct_mark) {
WC_UNMASK_FIELD(wc, ct_mark);
}
- if (ovs_u128_is_zero(&flow->ct_label)) {
+ if (ovs_u128_is_zero(flow->ct_label)) {
WC_UNMASK_FIELD(wc, ct_label);
}
for (int i = 0; i < FLOW_N_REGS; i++) {
FLOWMAP_SET(map, nw_frag);
FLOWMAP_SET(map, nw_tos);
FLOWMAP_SET(map, nw_ttl);
+ FLOWMAP_SET(map, tp_src);
+ FLOWMAP_SET(map, tp_dst);
if (OVS_UNLIKELY(flow->nw_proto == IPPROTO_IGMP)) {
FLOWMAP_SET(map, igmp_group_ip4);
} else {
FLOWMAP_SET(map, tcp_flags);
- FLOWMAP_SET(map, tp_src);
- FLOWMAP_SET(map, tp_dst);
}
} else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
FLOWMAP_SET(map, ipv6_src);
FLOWMAP_SET(map, nw_frag);
FLOWMAP_SET(map, nw_tos);
FLOWMAP_SET(map, nw_ttl);
+ FLOWMAP_SET(map, tp_src);
+ FLOWMAP_SET(map, tp_dst);
if (OVS_UNLIKELY(flow->nw_proto == IPPROTO_ICMPV6)) {
FLOWMAP_SET(map, nd_target);
FLOWMAP_SET(map, arp_tha);
} else {
FLOWMAP_SET(map, tcp_flags);
- FLOWMAP_SET(map, tp_src);
- FLOWMAP_SET(map, tp_dst);
}
} else if (eth_type_mpls(flow->dl_type)) {
FLOWMAP_SET(map, mpls_lse);
uint32_t
miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis)
{
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 35);
uint32_t hash = basis;
if (flow) {
ovs_be16 dl_type = MINIFLOW_GET_BE16(flow, dl_type);
+ uint8_t nw_proto;
- hash = hash_add(hash, MINIFLOW_GET_U8(flow, nw_proto));
-
- /* Separate loops for better optimization. */
if (dl_type == htons(ETH_TYPE_IPV6)) {
struct flowmap map = FLOWMAP_EMPTY_INITIALIZER;
uint64_t value;
MINIFLOW_FOR_EACH_IN_FLOWMAP(value, flow, map) {
hash = hash_add64(hash, value);
}
- } else {
+ } else if (dl_type == htons(ETH_TYPE_IP)
+ || dl_type == htons(ETH_TYPE_ARP)) {
hash = hash_add(hash, MINIFLOW_GET_U32(flow, nw_src));
hash = hash_add(hash, MINIFLOW_GET_U32(flow, nw_dst));
+ } else {
+ goto out;
}
+
+ nw_proto = MINIFLOW_GET_U8(flow, nw_proto);
+ hash = hash_add(hash, nw_proto);
+ if (nw_proto != IPPROTO_TCP && nw_proto != IPPROTO_UDP
+ && nw_proto != IPPROTO_SCTP && nw_proto != IPPROTO_ICMP
+ && nw_proto != IPPROTO_ICMPV6) {
+ goto out;
+ }
+
/* Add both ports at once. */
hash = hash_add(hash, MINIFLOW_GET_U32(flow, tp_src));
- hash = hash_finish(hash, 42); /* Arbitrary number. */
}
- return hash;
+out:
+ return hash_finish(hash, 42);
}
ASSERT_SEQUENTIAL_SAME_WORD(tp_src, tp_dst);
uint32_t
flow_hash_5tuple(const struct flow *flow, uint32_t basis)
{
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 35);
uint32_t hash = basis;
if (flow) {
- hash = hash_add(hash, flow->nw_proto);
if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
const uint64_t *flow_u64 = (const uint64_t *)flow;
for (;ofs < end; ofs++) {
hash = hash_add64(hash, flow_u64[ofs]);
}
- } else {
+ } else if (flow->dl_type == htons(ETH_TYPE_IP)
+ || flow->dl_type == htons(ETH_TYPE_ARP)) {
hash = hash_add(hash, (OVS_FORCE uint32_t) flow->nw_src);
hash = hash_add(hash, (OVS_FORCE uint32_t) flow->nw_dst);
+ } else {
+ goto out;
}
+
+ hash = hash_add(hash, flow->nw_proto);
+ if (flow->nw_proto != IPPROTO_TCP && flow->nw_proto != IPPROTO_UDP
+ && flow->nw_proto != IPPROTO_SCTP && flow->nw_proto != IPPROTO_ICMP
+ && flow->nw_proto != IPPROTO_ICMPV6) {
+ goto out;
+ }
+
/* Add both ports at once. */
hash = hash_add(hash,
((const uint32_t *)flow)[offsetof(struct flow, tp_src)
/ sizeof(uint32_t)]);
- hash = hash_finish(hash, 42); /* Arbitrary number. */
}
- return hash;
+out:
+ return hash_finish(hash, 42); /* Arbitrary number. */
}
/* Hashes 'flow' based on its L2 through L4 protocol information. */