/*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * 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.
#include "dynamic-string.h"
#include "ofp-util.h"
#include "packets.h"
+#include "tun-metadata.h"
/* Converts the flow in 'flow' into a match in 'match', with the given
* 'wildcards'. */
match->flow = *flow;
match->wc = *wc;
match_zero_wildcarded_fields(match);
+ memset(&match->tun_md, 0, sizeof match->tun_md);
}
/* Converts a flow into a match. It sets the wildcard masks based on
flow_wildcards_init_for_packet(&match->wc, flow);
WC_MASK_FIELD(&match->wc, regs);
WC_MASK_FIELD(&match->wc, metadata);
+
+ memset(&match->tun_md, 0, sizeof match->tun_md);
}
/* Initializes 'match' as a "catch-all" match that matches every packet. */
{
memset(&match->flow, 0, sizeof match->flow);
flow_wildcards_init_catchall(&match->wc);
+ memset(&match->tun_md, 0, sizeof match->tun_md);
}
/* For each bit or field wildcarded in 'match', sets the corresponding bit or
match->wc.masks.recirc_id = UINT32_MAX;
}
+void
+match_set_conj_id(struct match *match, uint32_t value)
+{
+ match->flow.conj_id = value;
+ match->wc.masks.conj_id = UINT32_MAX;
+}
+
void
match_set_reg(struct match *match, unsigned int reg_idx, uint32_t value)
{
flow_set_xreg(&match->flow, xreg_idx, value & mask);
}
+void
+match_set_actset_output(struct match *match, ofp_port_t actset_output)
+{
+ match->wc.masks.actset_output = u16_to_ofp(UINT16_MAX);
+ match->flow.actset_output = actset_output;
+}
+
void
match_set_metadata(struct match *match, ovs_be64 metadata)
{
match->flow.tunnel.flags = flags & mask;
}
+void
+match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16 mask)
+{
+ match->wc.masks.tunnel.gbp_id = mask;
+ match->flow.tunnel.gbp_id = gbp_id & mask;
+}
+
+void
+match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id)
+{
+ match_set_tun_gbp_id_masked(match, gbp_id, OVS_BE16_MAX);
+}
+
+void
+match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask)
+{
+ match->wc.masks.tunnel.gbp_flags = mask;
+ match->flow.tunnel.gbp_flags = flags & mask;
+}
+
+void
+match_set_tun_gbp_flags(struct match *match, uint8_t flags)
+{
+ match_set_tun_gbp_flags_masked(match, flags, UINT8_MAX);
+}
+
void
match_set_in_port(struct match *match, ofp_port_t ofp_port)
{
format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src);
format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst);
+ if (wc->masks.tunnel.gbp_id) {
+ format_be16_masked(s, "tun_gbp_id", tnl->gbp_id,
+ wc->masks.tunnel.gbp_id);
+ }
+
+ if (wc->masks.tunnel.gbp_flags) {
+ ds_put_format(s, "tun_gbp_flags=%#"PRIx8",", tnl->gbp_flags);
+ }
+
if (wc->masks.tunnel.ip_tos) {
ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
}
format_flags(s, flow_tun_flag_to_string, tnl->flags, '|');
ds_put_char(s, ',');
}
+ tun_metadata_match_format(s, match);
}
/* Appends a string representation of 'match' to 's'. If 'priority' is
int i;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 32);
if (priority != OFP_DEFAULT_PRIORITY) {
ds_put_format(s, "priority=%d,", priority);
wc->masks.recirc_id);
}
- if (f->dp_hash && wc->masks.dp_hash) {
+ if (wc->masks.dp_hash) {
format_uint32_masked(s, "dp_hash", f->dp_hash,
wc->masks.dp_hash);
}
+ if (wc->masks.conj_id) {
+ ds_put_format(s, "conj_id=%"PRIu32",", f->conj_id);
+ }
+
if (wc->masks.skb_priority) {
ds_put_format(s, "skb_priority=%#"PRIx32",", f->skb_priority);
}
+ if (wc->masks.actset_output) {
+ ds_put_cstr(s, "actset_output=");
+ ofputil_format_port(f->actset_output, s);
+ ds_put_char(s, ',');
+ }
+
if (wc->masks.dl_type) {
skip_type = true;
if (f->dl_type == htons(ETH_TYPE_IP)) {
}
}
- if (s->length > start_len && ds_last(s) == ',') {
- s->length--;
+ if (s->length > start_len) {
+ ds_chomp(s, ',');
}
}
{
miniflow_expand(&src->flow, &dst->flow);
minimask_expand(&src->mask, &dst->wc);
+ memset(&dst->tun_md, 0, sizeof dst->tun_md);
}
/* Returns true if 'a' and 'b' match the same packets, false otherwise. */
minimatch_matches_flow(const struct minimatch *match,
const struct flow *target)
{
- const uint32_t *target_u32 = (const uint32_t *) target;
- const uint32_t *flowp = miniflow_get_u32_values(&match->flow);
- const uint32_t *maskp = miniflow_get_u32_values(&match->mask.masks);
- uint64_t map;
+ const uint64_t *target_u64 = (const uint64_t *) target;
+ const uint64_t *flowp = miniflow_get_values(&match->flow);
+ const uint64_t *maskp = miniflow_get_values(&match->mask.masks);
+ int idx;
- for (map = match->flow.map; map; map = zero_rightmost_1bit(map)) {
- if ((*flowp++ ^ target_u32[raw_ctz(map)]) & *maskp++) {
+ MAP_FOR_EACH_INDEX(idx, match->flow.map) {
+ if ((*flowp++ ^ target_u64[idx]) & *maskp++) {
return false;
}
}