mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
Implement arbitrary bitwise masks for tun_id field.
This was documented to work, but not implemented. Requested-by: Pankaj Thakkar <thakkar@nicira.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -130,8 +130,15 @@ cls_rule_set_reg_masked(struct cls_rule *rule, unsigned int reg_idx,
|
||||
void
|
||||
cls_rule_set_tun_id(struct cls_rule *rule, ovs_be64 tun_id)
|
||||
{
|
||||
rule->wc.wildcards &= ~FWW_TUN_ID;
|
||||
rule->flow.tun_id = tun_id;
|
||||
cls_rule_set_tun_id_masked(rule, tun_id, htonll(UINT64_MAX));
|
||||
}
|
||||
|
||||
void
|
||||
cls_rule_set_tun_id_masked(struct cls_rule *rule,
|
||||
ovs_be64 tun_id, ovs_be64 mask)
|
||||
{
|
||||
rule->wc.tun_id_mask = mask;
|
||||
rule->flow.tun_id = tun_id & mask;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -393,8 +400,16 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!(w & FWW_TUN_ID)) {
|
||||
ds_put_format(s, "tun_id=0x%"PRIx64",", ntohll(f->tun_id));
|
||||
switch (wc->tun_id_mask) {
|
||||
case 0:
|
||||
break;
|
||||
case CONSTANT_HTONLL(UINT64_MAX):
|
||||
ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(f->tun_id));
|
||||
break;
|
||||
default:
|
||||
ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",",
|
||||
ntohll(f->tun_id), ntohll(wc->tun_id_mask));
|
||||
break;
|
||||
}
|
||||
if (!(w & FWW_IN_PORT)) {
|
||||
ds_put_format(s, "in_port=%"PRIu16",",
|
||||
@@ -940,7 +955,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
|
||||
}
|
||||
}
|
||||
|
||||
return ((wc & FWW_TUN_ID || a->tun_id == b->tun_id)
|
||||
return (!((a->tun_id ^ b->tun_id) & wildcards->tun_id_mask)
|
||||
&& !((a->nw_src ^ b->nw_src) & wildcards->nw_src_mask)
|
||||
&& !((a->nw_dst ^ b->nw_dst) & wildcards->nw_dst_mask)
|
||||
&& (wc & FWW_IN_PORT || a->in_port == b->in_port)
|
||||
@@ -973,9 +988,7 @@ zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
|
||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||
flow->regs[i] &= wildcards->reg_masks[i];
|
||||
}
|
||||
if (wc & FWW_TUN_ID) {
|
||||
flow->tun_id = 0;
|
||||
}
|
||||
flow->tun_id &= wildcards->tun_id_mask;
|
||||
flow->nw_src &= wildcards->nw_src_mask;
|
||||
flow->nw_dst &= wildcards->nw_dst_mask;
|
||||
if (wc & FWW_IN_PORT) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -78,6 +78,8 @@ void cls_rule_set_reg(struct cls_rule *, unsigned int reg_idx, uint32_t value);
|
||||
void cls_rule_set_reg_masked(struct cls_rule *, unsigned int reg_idx,
|
||||
uint32_t value, uint32_t mask);
|
||||
void cls_rule_set_tun_id(struct cls_rule *, ovs_be64 tun_id);
|
||||
void cls_rule_set_tun_id_masked(struct cls_rule *,
|
||||
ovs_be64 tun_id, ovs_be64 mask);
|
||||
void cls_rule_set_in_port(struct cls_rule *, uint16_t odp_port);
|
||||
void cls_rule_set_dl_type(struct cls_rule *, ovs_be16);
|
||||
void cls_rule_set_dl_src(struct cls_rule *, const uint8_t[6]);
|
||||
|
10
lib/flow.c
10
lib/flow.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -302,6 +302,7 @@ void
|
||||
flow_wildcards_init_catchall(struct flow_wildcards *wc)
|
||||
{
|
||||
wc->wildcards = FWW_ALL;
|
||||
wc->tun_id_mask = htonll(0);
|
||||
wc->nw_src_mask = htonl(0);
|
||||
wc->nw_dst_mask = htonl(0);
|
||||
memset(wc->reg_masks, 0, sizeof wc->reg_masks);
|
||||
@@ -315,6 +316,7 @@ void
|
||||
flow_wildcards_init_exact(struct flow_wildcards *wc)
|
||||
{
|
||||
wc->wildcards = 0;
|
||||
wc->tun_id_mask = htonll(UINT64_MAX);
|
||||
wc->nw_src_mask = htonl(UINT32_MAX);
|
||||
wc->nw_dst_mask = htonl(UINT32_MAX);
|
||||
memset(wc->reg_masks, 0xff, sizeof wc->reg_masks);
|
||||
@@ -330,6 +332,7 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc)
|
||||
int i;
|
||||
|
||||
if (wc->wildcards
|
||||
|| wc->tun_id_mask != htonll(UINT64_MAX)
|
||||
|| wc->nw_src_mask != htonl(UINT32_MAX)
|
||||
|| wc->nw_dst_mask != htonl(UINT32_MAX)
|
||||
|| wc->vlan_tci_mask != htons(UINT16_MAX)) {
|
||||
@@ -356,6 +359,7 @@ flow_wildcards_combine(struct flow_wildcards *dst,
|
||||
int i;
|
||||
|
||||
dst->wildcards = src1->wildcards | src2->wildcards;
|
||||
dst->tun_id_mask = src1->tun_id_mask & src2->tun_id_mask;
|
||||
dst->nw_src_mask = src1->nw_src_mask & src2->nw_src_mask;
|
||||
dst->nw_dst_mask = src1->nw_dst_mask & src2->nw_dst_mask;
|
||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||
@@ -371,7 +375,7 @@ flow_wildcards_hash(const struct flow_wildcards *wc)
|
||||
/* If you change struct flow_wildcards and thereby trigger this
|
||||
* assertion, please check that the new struct flow_wildcards has no holes
|
||||
* in it before you update the assertion. */
|
||||
BUILD_ASSERT_DECL(sizeof *wc == 16 + FLOW_N_REGS * 4);
|
||||
BUILD_ASSERT_DECL(sizeof *wc == 24 + FLOW_N_REGS * 4);
|
||||
return hash_bytes(wc, sizeof *wc, 0);
|
||||
}
|
||||
|
||||
@@ -384,6 +388,7 @@ flow_wildcards_equal(const struct flow_wildcards *a,
|
||||
int i;
|
||||
|
||||
if (a->wildcards != b->wildcards
|
||||
|| a->tun_id_mask != b->tun_id_mask
|
||||
|| a->nw_src_mask != b->nw_src_mask
|
||||
|| a->nw_dst_mask != b->nw_dst_mask
|
||||
|| a->vlan_tci_mask != b->vlan_tci_mask) {
|
||||
@@ -414,6 +419,7 @@ flow_wildcards_has_extra(const struct flow_wildcards *a,
|
||||
}
|
||||
|
||||
return (a->wildcards & ~b->wildcards
|
||||
|| (a->tun_id_mask & b->tun_id_mask) != b->tun_id_mask
|
||||
|| (a->nw_src_mask & b->nw_src_mask) != b->nw_src_mask
|
||||
|| (a->nw_dst_mask & b->nw_dst_mask) != b->nw_dst_mask
|
||||
|| (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -107,18 +107,17 @@ typedef unsigned int OVS_BITWISE flow_wildcards_t;
|
||||
#define FWW_TP_DST ((OVS_FORCE flow_wildcards_t) (1 << 7))
|
||||
/* Same meanings as corresponding OFPFW_* bits, but differ in value. */
|
||||
#define FWW_NW_TOS ((OVS_FORCE flow_wildcards_t) (1 << 1))
|
||||
/* No OFPFW_* bits, but they do have corresponding OVSFW_* bits. */
|
||||
#define FWW_TUN_ID ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
||||
/* No corresponding OFPFW_* or OVSFW_* bits. */
|
||||
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 9))
|
||||
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
||||
/* multicast bit only */
|
||||
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 10)) - 1))
|
||||
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 9)) - 1))
|
||||
|
||||
/* Information on wildcards for a flow, as a supplement to "struct flow".
|
||||
*
|
||||
* Note that the meaning of 1-bits in 'wildcards' is opposite that of 1-bits in
|
||||
* the rest of the members. */
|
||||
struct flow_wildcards {
|
||||
ovs_be64 tun_id_mask; /* 1-bit in each significant tun_id bit. */
|
||||
flow_wildcards_t wildcards; /* 1-bit in each FWW_* wildcarded field. */
|
||||
uint32_t reg_masks[FLOW_N_REGS]; /* 1-bit in each significant regs bit. */
|
||||
ovs_be32 nw_src_mask; /* 1-bit in each significant nw_src bit. */
|
||||
|
@@ -320,8 +320,21 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
|
||||
|
||||
/* Tunnel ID. */
|
||||
case NFI_NXM_NX_TUN_ID:
|
||||
flow->tun_id = get_unaligned_be64(value);
|
||||
return 0;
|
||||
if (wc->tun_id_mask) {
|
||||
return NXM_DUP_TYPE;
|
||||
} else {
|
||||
cls_rule_set_tun_id(rule, get_unaligned_be64(value));
|
||||
return 0;
|
||||
}
|
||||
case NFI_NXM_NX_TUN_ID_W:
|
||||
if (wc->tun_id_mask) {
|
||||
return NXM_DUP_TYPE;
|
||||
} else {
|
||||
ovs_be64 tun_id = get_unaligned_be64(value);
|
||||
ovs_be64 tun_mask = get_unaligned_be64(mask);
|
||||
cls_rule_set_tun_id_masked(rule, tun_id, tun_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Registers. */
|
||||
case NFI_NXM_NX_REG0:
|
||||
@@ -533,6 +546,31 @@ nxm_put_64(struct ofpbuf *b, uint32_t header, ovs_be64 value)
|
||||
ofpbuf_put(b, &value, sizeof value);
|
||||
}
|
||||
|
||||
static void
|
||||
nxm_put_64w(struct ofpbuf *b, uint32_t header, ovs_be64 value, ovs_be64 mask)
|
||||
{
|
||||
nxm_put_header(b, header);
|
||||
ofpbuf_put(b, &value, sizeof value);
|
||||
ofpbuf_put(b, &mask, sizeof mask);
|
||||
}
|
||||
|
||||
static void
|
||||
nxm_put_64m(struct ofpbuf *b, uint32_t header, ovs_be64 value, ovs_be64 mask)
|
||||
{
|
||||
switch (mask) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case CONSTANT_HTONLL(UINT64_MAX):
|
||||
nxm_put_64(b, header, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
nxm_put_64w(b, NXM_MAKE_WILD_HEADER(header), value, mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nxm_put_eth(struct ofpbuf *b, uint32_t header,
|
||||
const uint8_t value[ETH_ADDR_LEN])
|
||||
@@ -657,9 +695,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
|
||||
}
|
||||
|
||||
/* Tunnel ID. */
|
||||
if (!(wc & FWW_TUN_ID)) {
|
||||
nxm_put_64(b, NXM_NX_TUN_ID, flow->tun_id);
|
||||
}
|
||||
nxm_put_64m(b, NXM_NX_TUN_ID, flow->tun_id, cr->wc.tun_id_mask);
|
||||
|
||||
/* Registers. */
|
||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||
@@ -1125,6 +1161,7 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow)
|
||||
#error
|
||||
#endif
|
||||
|
||||
case NFI_NXM_NX_TUN_ID_W:
|
||||
case NFI_NXM_OF_ETH_DST_W:
|
||||
case NFI_NXM_OF_VLAN_TCI_W:
|
||||
case NFI_NXM_OF_IP_SRC_W:
|
||||
@@ -1189,6 +1226,7 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow,
|
||||
case NFI_NXM_OF_UDP_DST:
|
||||
case NFI_NXM_OF_ICMP_TYPE:
|
||||
case NFI_NXM_OF_ICMP_CODE:
|
||||
case NFI_NXM_NX_TUN_ID_W:
|
||||
case NFI_NXM_OF_ETH_DST_W:
|
||||
case NFI_NXM_OF_VLAN_TCI_W:
|
||||
case NFI_NXM_OF_IP_SRC_W:
|
||||
|
@@ -38,7 +38,7 @@ DEFINE_FIELD (OF_ICMP_CODE, FWW_TP_DST, ETH_TYPE_IP, IP_TYPE_ICMP, false)
|
||||
DEFINE_FIELD (OF_ARP_OP, FWW_NW_PROTO, ETH_TYPE_ARP, 0, false)
|
||||
DEFINE_FIELD_M(OF_ARP_SPA, 0, ETH_TYPE_ARP, 0, false)
|
||||
DEFINE_FIELD_M(OF_ARP_TPA, 0, ETH_TYPE_ARP, 0, false)
|
||||
DEFINE_FIELD (NX_TUN_ID, FWW_TUN_ID, 0, 0, true)
|
||||
DEFINE_FIELD_M(NX_TUN_ID, 0, 0, 0, true)
|
||||
|
||||
DEFINE_FIELD_M(NX_REG0, 0, 0, 0, true)
|
||||
#if FLOW_N_REGS >= 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Nicira Networks.
|
||||
* Copyright (c) 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -128,6 +128,35 @@ str_to_ip(const char *str_, ovs_be32 *ip, ovs_be32 *maskp)
|
||||
free(str);
|
||||
}
|
||||
|
||||
static void
|
||||
str_to_tun_id(const char *str, ovs_be64 *tun_idp, ovs_be64 *maskp)
|
||||
{
|
||||
uint64_t tun_id, mask;
|
||||
char *tail;
|
||||
|
||||
errno = 0;
|
||||
tun_id = strtoull(str, &tail, 0);
|
||||
if (errno || (*tail != '\0' && *tail != '/')) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (*tail == '/') {
|
||||
mask = strtoull(tail + 1, &tail, 0);
|
||||
if (errno || *tail != '\0') {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
mask = UINT64_MAX;
|
||||
}
|
||||
|
||||
*tun_idp = htonll(tun_id);
|
||||
*maskp = htonll(mask);
|
||||
return;
|
||||
|
||||
error:
|
||||
ovs_fatal(0, "%s: bad syntax for tunnel id", str);
|
||||
}
|
||||
|
||||
static void *
|
||||
put_action(struct ofpbuf *b, size_t size, uint16_t type)
|
||||
{
|
||||
@@ -448,7 +477,7 @@ parse_protocol(const char *name, const struct protocol **p_out)
|
||||
}
|
||||
|
||||
#define FIELDS \
|
||||
FIELD(F_TUN_ID, "tun_id", FWW_TUN_ID) \
|
||||
FIELD(F_TUN_ID, "tun_id", 0) \
|
||||
FIELD(F_IN_PORT, "in_port", FWW_IN_PORT) \
|
||||
FIELD(F_DL_VLAN, "dl_vlan", 0) \
|
||||
FIELD(F_DL_VLAN_PCP, "dl_vlan_pcp", 0) \
|
||||
@@ -502,12 +531,14 @@ parse_field_value(struct cls_rule *rule, enum field_index index,
|
||||
const char *value)
|
||||
{
|
||||
uint8_t mac[ETH_ADDR_LEN];
|
||||
ovs_be64 tun_id, tun_mask;
|
||||
ovs_be32 ip, mask;
|
||||
uint16_t port_no;
|
||||
|
||||
switch (index) {
|
||||
case F_TUN_ID:
|
||||
cls_rule_set_tun_id(rule, htonll(str_to_u64(value)));
|
||||
str_to_tun_id(value, &tun_id, &tun_mask);
|
||||
cls_rule_set_tun_id_masked(rule, tun_id, tun_mask);
|
||||
break;
|
||||
|
||||
case F_IN_PORT:
|
||||
|
@@ -132,9 +132,6 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
|
||||
|
||||
if (flow_format == NXFF_TUN_ID_FROM_COOKIE && !(ofpfw & NXFW_TUN_ID)) {
|
||||
rule->flow.tun_id = htonll(ntohll(cookie) >> 32);
|
||||
} else {
|
||||
wc->wildcards |= FWW_TUN_ID;
|
||||
rule->flow.tun_id = htonll(0);
|
||||
}
|
||||
|
||||
if (ofpfw & OFPFW_DL_DST) {
|
||||
@@ -233,7 +230,7 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule,
|
||||
|
||||
/* Tunnel ID. */
|
||||
if (flow_format == NXFF_TUN_ID_FROM_COOKIE) {
|
||||
if (wc->wildcards & FWW_TUN_ID) {
|
||||
if (wc->tun_id_mask == htonll(0)) {
|
||||
ofpfw |= NXFW_TUN_ID;
|
||||
} else {
|
||||
uint32_t cookie_lo = ntohll(cookie_in);
|
||||
@@ -829,6 +826,47 @@ regs_fully_wildcarded(const struct flow_wildcards *wc)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_nxm_required(const struct cls_rule *rule, bool cookie_support,
|
||||
ovs_be64 cookie)
|
||||
{
|
||||
const struct flow_wildcards *wc = &rule->wc;
|
||||
ovs_be32 cookie_hi;
|
||||
|
||||
/* Only NXM supports separately wildcards the Ethernet multicast bit. */
|
||||
if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Only NXM supports matching registers. */
|
||||
if (!regs_fully_wildcarded(wc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (wc->tun_id_mask) {
|
||||
case CONSTANT_HTONLL(0):
|
||||
/* Other formats can fully wildcard tun_id. */
|
||||
break;
|
||||
|
||||
case CONSTANT_HTONLL(UINT64_MAX):
|
||||
/* Only NXM supports matching tunnel ID, unless there is a cookie and
|
||||
* the top 32 bits of the cookie are the desired tunnel ID value. */
|
||||
cookie_hi = htonl(ntohll(cookie) >> 32);
|
||||
if (!cookie_support
|
||||
|| (cookie_hi && cookie_hi != ntohll(rule->flow.tun_id))) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Only NXM supports partial matches on tunnel ID. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Other formats can express this rule. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns the minimum nx_flow_format to use for sending 'rule' to a switch
|
||||
* (e.g. to add or remove a flow). 'cookie_support' should be true if the
|
||||
* command to be sent includes a flow cookie (as OFPT_FLOW_MOD does, for
|
||||
@@ -853,16 +891,9 @@ enum nx_flow_format
|
||||
ofputil_min_flow_format(const struct cls_rule *rule, bool cookie_support,
|
||||
ovs_be64 cookie)
|
||||
{
|
||||
const struct flow_wildcards *wc = &rule->wc;
|
||||
ovs_be32 cookie_hi = htonl(ntohll(cookie) >> 32);
|
||||
|
||||
if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)
|
||||
|| !regs_fully_wildcarded(wc)
|
||||
|| (!(wc->wildcards & FWW_TUN_ID)
|
||||
&& (!cookie_support
|
||||
|| (cookie_hi && cookie_hi != ntohll(rule->flow.tun_id))))) {
|
||||
if (is_nxm_required(rule, cookie_support, cookie)) {
|
||||
return NXFF_NXM;
|
||||
} else if (!(wc->wildcards & FWW_TUN_ID)) {
|
||||
} else if (rule->wc.tun_id_mask != htonll(0)) {
|
||||
return NXFF_TUN_ID_FROM_COOKIE;
|
||||
} else {
|
||||
return NXFF_OPENFLOW10;
|
||||
|
@@ -15,6 +15,7 @@ tun_id=0x1234,cookie=0x5678,actions=flood
|
||||
actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel:0x123456789
|
||||
actions=multipath(eth_src, 50, hrw, 12, 0, NXM_NX_REG0[0..3]),multipath(symmetric_l4, 1024, iter_hash, 5000, 5050, NXM_NX_REG0[0..12])
|
||||
actions=drop
|
||||
tun_id=0x1234000056780000/0xffff0000ffff0000,actions=drop
|
||||
]])
|
||||
AT_CHECK([ovs-ofctl parse-flows flows.txt
|
||||
], [0], [stdout], [stderr])
|
||||
@@ -32,6 +33,8 @@ OFPT_FLOW_MOD: ADD cookie:0x123400005678 actions=FLOOD
|
||||
OFPT_FLOW_MOD: ADD actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel64:0x123456789
|
||||
OFPT_FLOW_MOD: ADD actions=multipath(eth_src,50,hrw,12,0,NXM_NX_REG0[0..3]),multipath(symmetric_l4,1024,iter_hash,5000,5050,NXM_NX_REG0[0..12])
|
||||
OFPT_FLOW_MOD: ADD actions=drop
|
||||
NXT_SET_FLOW_FORMAT: format=nxm
|
||||
NXT_FLOW_MOD: ADD tun_id=0x1234000056780000/0xffff0000ffff0000 actions=drop
|
||||
]])
|
||||
AT_CHECK([sed 's/.*|//' stderr], [0], [dnl
|
||||
normalization changed ofp_match, details:
|
||||
@@ -65,6 +68,7 @@ cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
|
||||
actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
|
||||
tun_id=0x1234,cookie=0x5678,actions=flood
|
||||
actions=drop
|
||||
tun_id=0x1234000056780000/0xffff0000ffff0000,actions=drop
|
||||
])
|
||||
AT_CHECK([ovs-ofctl -F nxm parse-flows flows.txt], [0], [stdout])
|
||||
AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0], [dnl
|
||||
@@ -78,6 +82,7 @@ NXT_FLOW_MOD: ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTRO
|
||||
NXT_FLOW_MOD: ADD actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00
|
||||
NXT_FLOW_MOD: ADD tun_id=0x1234 cookie:0x5678 actions=FLOOD
|
||||
NXT_FLOW_MOD: ADD actions=drop
|
||||
NXT_FLOW_MOD: ADD tun_id=0x1234000056780000/0xffff0000ffff0000 actions=drop
|
||||
])
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -214,6 +219,7 @@ NXM_OF_ARP_TPA_W(C0D80000/FFFF0000)
|
||||
|
||||
# Tunnel ID.
|
||||
NXM_NX_TUN_ID(00000000abcdef01)
|
||||
NXM_NX_TUN_ID_W(84200000abcdef01/84200000FFFFFFFF)
|
||||
|
||||
# Register 0.
|
||||
NXM_NX_REG0(acebdf56)
|
||||
@@ -331,6 +337,7 @@ nx_pull_match() returned error 44010104
|
||||
|
||||
# Tunnel ID.
|
||||
NXM_NX_TUN_ID(00000000abcdef01)
|
||||
NXM_NX_TUN_ID_W(84200000abcdef01/84200000ffffffff)
|
||||
|
||||
# Register 0.
|
||||
NXM_NX_REG0(acebdf56)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@
|
||||
/* struct flow all-caps */ \
|
||||
/* FWW_* bit(s) member name name */ \
|
||||
/* -------------------------- ----------- -------- */ \
|
||||
CLS_FIELD(FWW_TUN_ID, tun_id, TUN_ID) \
|
||||
CLS_FIELD(0, tun_id, TUN_ID) \
|
||||
CLS_FIELD(0, nw_src, NW_SRC) \
|
||||
CLS_FIELD(0, nw_dst, NW_DST) \
|
||||
CLS_FIELD(FWW_IN_PORT, in_port, IN_PORT) \
|
||||
@@ -201,6 +201,8 @@ match(const struct cls_rule *wild, const struct flow *fixed)
|
||||
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
||||
eq = !((fixed->vlan_tci ^ wild->flow.vlan_tci)
|
||||
& wild->wc.vlan_tci_mask);
|
||||
} else if (f_idx == CLS_F_IDX_TUN_ID) {
|
||||
eq = !((fixed->tun_id ^ wild->flow.tun_id) & wild->wc.tun_id_mask);
|
||||
} else {
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -463,6 +465,8 @@ make_rule(int wc_fields, unsigned int priority, int value_pat)
|
||||
rule->cls_rule.wc.nw_dst_mask = htonl(UINT32_MAX);
|
||||
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
||||
rule->cls_rule.wc.vlan_tci_mask = htons(UINT16_MAX);
|
||||
} else if (f_idx == CLS_F_IDX_TUN_ID) {
|
||||
rule->cls_rule.wc.tun_id_mask = htonll(UINT64_MAX);
|
||||
} else {
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
@@ -337,20 +337,25 @@ as a decimal number between 0 and 255, inclusive.
|
||||
.IP
|
||||
When \fBdl_type\fR and \fBnw_proto\fR take other values, the values of
|
||||
these settings are ignored (see \fBFlow Syntax\fR above).
|
||||
.IP \fBtun_id=\fItunnel\-id\fR
|
||||
Matches tunnel identifier \fItunnel\-id\fR. Only packets that arrive
|
||||
.IP \fBtun_id=\fItunnel-id\fR[\fB/\fImask\fR]
|
||||
Matches tunnel identifier \fItunnel-id\fR. Only packets that arrive
|
||||
over a tunnel that carries a key (e.g. GRE with the RFC 2890 key
|
||||
extension) will have a nonzero tunnel ID.
|
||||
extension) will have a nonzero tunnel ID. If \fImask\fR is omitted,
|
||||
\fItunnel-id\fR is the exact tunnel ID to match; \fImask\fR is
|
||||
specified, then a 1-bit in \fImask\fR indicates that the corresponding
|
||||
bit in \fItunnel-id\fR must match exactly, and a 0-bit wildcards that
|
||||
bit.
|
||||
.IP
|
||||
\fBtun_id\fR requires use of one of two Nicira extensions to OpenFlow:
|
||||
.RS
|
||||
.IP "NXM (Nicira Extended Match)"
|
||||
This extension fully supports \fBtun_id\fR.
|
||||
.IP "Tunnel ID from Cookie"
|
||||
This extension supports \fBtun_id\fR with two caveats: the top 32 bits
|
||||
of the \fBcookie\fR (see below) are used for \fItunnel\-id\fR and thus
|
||||
unavailable for other use, and specifying \fBtun_id\fR on
|
||||
\fBdump\-flows\fR or \fBdump\-aggregate\fR has no effect.
|
||||
This extension supports \fBtun_id\fR with three caveats: the top 32 bits
|
||||
of the \fBcookie\fR (see below) are used for \fItunnel-id\fR and thus
|
||||
unavailable for other use, specifying \fBtun_id\fR on
|
||||
\fBdump\-flows\fR or \fBdump\-aggregate\fR has no effect, and
|
||||
\fImask\fR is not supported.
|
||||
.RE
|
||||
.IP
|
||||
When \fBtun_id\fR is specified, \fBovs\-ofctl\fR will automatically
|
||||
|
Reference in New Issue
Block a user