mirror of
https://github.com/openvswitch/ovs
synced 2025-10-29 15:28:56 +00:00
Add connection tracking label support.
This patch adds a new 128-bit metadata field to the connection tracking
interface. When a label is specified as part of the ct action and the
connection is committed, the value is saved with the current connection.
Subsequent ct lookups with the table specified will expose this metadata
as the "ct_label" field in the flow.
For example, to allow new TCP connections from port 1->2 and only allow
established connections from port 2->1, and to associate a label with
those connections:
table=0,priority=1,action=drop
table=0,arp,action=normal
table=0,in_port=1,tcp,action=ct(commit,exec(set_field:1->ct_label)),2
table=0,in_port=2,ct_state=-trk,tcp,action=ct(table=1)
table=1,in_port=2,ct_state=+trk,ct_label=1,tcp,action=1
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
40
lib/match.c
40
lib/match.c
@@ -318,6 +318,24 @@ match_set_ct_mark_masked(struct match *match, uint32_t ct_mark,
|
||||
match->wc.masks.ct_mark = mask;
|
||||
}
|
||||
|
||||
void
|
||||
match_set_ct_label(struct match *match, ovs_u128 ct_label)
|
||||
{
|
||||
ovs_u128 mask;
|
||||
|
||||
mask.u64.lo = UINT64_MAX;
|
||||
mask.u64.hi = UINT64_MAX;
|
||||
match_set_ct_label_masked(match, ct_label, mask);
|
||||
}
|
||||
|
||||
void
|
||||
match_set_ct_label_masked(struct match *match, ovs_u128 value, ovs_u128 mask)
|
||||
{
|
||||
match->flow.ct_label.u64.lo = value.u64.lo & mask.u64.lo;
|
||||
match->flow.ct_label.u64.hi = value.u64.hi & mask.u64.hi;
|
||||
match->wc.masks.ct_label = mask;
|
||||
}
|
||||
|
||||
void
|
||||
match_set_dl_type(struct match *match, ovs_be16 dl_type)
|
||||
{
|
||||
@@ -957,6 +975,24 @@ format_flow_tunnel(struct ds *s, const struct match *match)
|
||||
tun_metadata_match_format(s, match);
|
||||
}
|
||||
|
||||
static void
|
||||
format_ct_label_masked(struct ds *s, const ovs_u128 *key, const ovs_u128 *mask)
|
||||
{
|
||||
if (!ovs_u128_is_zero(mask)) {
|
||||
ovs_be128 value;
|
||||
|
||||
hton128(key, &value);
|
||||
ds_put_format(s, "ct_label=");
|
||||
ds_put_hex(s, &value, sizeof value);
|
||||
if (!is_all_ones(mask, sizeof(*mask))) {
|
||||
hton128(mask, &value);
|
||||
ds_put_char(s, '/');
|
||||
ds_put_hex(s, &value, sizeof value);
|
||||
}
|
||||
ds_put_char(s, ',');
|
||||
}
|
||||
}
|
||||
|
||||
/* Appends a string representation of 'match' to 's'. If 'priority' is
|
||||
* different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
|
||||
void
|
||||
@@ -1025,6 +1061,10 @@ match_format(const struct match *match, struct ds *s, int priority)
|
||||
format_uint32_masked(s, "ct_mark", f->ct_mark, wc->masks.ct_mark);
|
||||
}
|
||||
|
||||
if (!ovs_u128_is_zero(&wc->masks.ct_label)) {
|
||||
format_ct_label_masked(s, &f->ct_label, &wc->masks.ct_label);
|
||||
}
|
||||
|
||||
if (wc->masks.dl_type) {
|
||||
skip_type = true;
|
||||
if (f->dl_type == htons(ETH_TYPE_IP)) {
|
||||
|
||||
Reference in New Issue
Block a user