mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 13:58:14 +00:00
Add support for bitwise matching on TCP and UDP ports.
Bug #8827. Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
3
NEWS
3
NEWS
@@ -8,6 +8,9 @@ post-v1.5.0
|
|||||||
documented in vswitchd/INTERNALS).
|
documented in vswitchd/INTERNALS).
|
||||||
- Load balancing can be disabled by setting the bond-rebalance-interval
|
- Load balancing can be disabled by setting the bond-rebalance-interval
|
||||||
to zero.
|
to zero.
|
||||||
|
- OpenFlow:
|
||||||
|
- Added support for bitwise matching on TCP and UDP ports.
|
||||||
|
See ovs-ofctl(8) for more information.
|
||||||
- Logging to console and file will have UTC timestamp as a default for all
|
- Logging to console and file will have UTC timestamp as a default for all
|
||||||
the daemons. An example of the default format is 2012-01-27T16:35:17Z.
|
the daemons. An example of the default format is 2012-01-27T16:35:17Z.
|
||||||
ovs-appctl can be used to change the default format as before.
|
ovs-appctl can be used to change the default format as before.
|
||||||
|
@@ -1398,9 +1398,12 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
|
|||||||
*
|
*
|
||||||
* Format: 16-bit integer in network byte order.
|
* Format: 16-bit integer in network byte order.
|
||||||
*
|
*
|
||||||
* Masking: Not maskable. */
|
* Masking: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
|
||||||
|
* earlier versions. */
|
||||||
#define NXM_OF_TCP_SRC NXM_HEADER (0x0000, 9, 2)
|
#define NXM_OF_TCP_SRC NXM_HEADER (0x0000, 9, 2)
|
||||||
|
#define NXM_OF_TCP_SRC_W NXM_HEADER_W(0x0000, 9, 2)
|
||||||
#define NXM_OF_TCP_DST NXM_HEADER (0x0000, 10, 2)
|
#define NXM_OF_TCP_DST NXM_HEADER (0x0000, 10, 2)
|
||||||
|
#define NXM_OF_TCP_DST_W NXM_HEADER_W(0x0000, 10, 2)
|
||||||
|
|
||||||
/* The source or destination port in the UDP header.
|
/* The source or destination port in the UDP header.
|
||||||
*
|
*
|
||||||
@@ -1410,9 +1413,12 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
|
|||||||
*
|
*
|
||||||
* Format: 16-bit integer in network byte order.
|
* Format: 16-bit integer in network byte order.
|
||||||
*
|
*
|
||||||
* Masking: Not maskable. */
|
* Masking: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
|
||||||
|
* earlier versions. */
|
||||||
#define NXM_OF_UDP_SRC NXM_HEADER (0x0000, 11, 2)
|
#define NXM_OF_UDP_SRC NXM_HEADER (0x0000, 11, 2)
|
||||||
|
#define NXM_OF_UDP_SRC_W NXM_HEADER_W(0x0000, 11, 2)
|
||||||
#define NXM_OF_UDP_DST NXM_HEADER (0x0000, 12, 2)
|
#define NXM_OF_UDP_DST NXM_HEADER (0x0000, 12, 2)
|
||||||
|
#define NXM_OF_UDP_DST_W NXM_HEADER_W(0x0000, 12, 2)
|
||||||
|
|
||||||
/* The type or code in the ICMP header.
|
/* The type or code in the ICMP header.
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
* Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -252,15 +252,27 @@ cls_rule_set_dl_vlan_pcp(struct cls_rule *rule, uint8_t dl_vlan_pcp)
|
|||||||
void
|
void
|
||||||
cls_rule_set_tp_src(struct cls_rule *rule, ovs_be16 tp_src)
|
cls_rule_set_tp_src(struct cls_rule *rule, ovs_be16 tp_src)
|
||||||
{
|
{
|
||||||
rule->wc.wildcards &= ~FWW_TP_SRC;
|
cls_rule_set_tp_src_masked(rule, tp_src, htons(UINT16_MAX));
|
||||||
rule->flow.tp_src = tp_src;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cls_rule_set_tp_src_masked(struct cls_rule *rule, ovs_be16 port, ovs_be16 mask)
|
||||||
|
{
|
||||||
|
rule->flow.tp_src = port & mask;
|
||||||
|
rule->wc.tp_src_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cls_rule_set_tp_dst(struct cls_rule *rule, ovs_be16 tp_dst)
|
cls_rule_set_tp_dst(struct cls_rule *rule, ovs_be16 tp_dst)
|
||||||
{
|
{
|
||||||
rule->wc.wildcards &= ~FWW_TP_DST;
|
cls_rule_set_tp_dst_masked(rule, tp_dst, htons(UINT16_MAX));
|
||||||
rule->flow.tp_dst = tp_dst;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cls_rule_set_tp_dst_masked(struct cls_rule *rule, ovs_be16 port, ovs_be16 mask)
|
||||||
|
{
|
||||||
|
rule->flow.tp_dst = port & mask;
|
||||||
|
rule->wc.tp_dst_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -340,15 +352,13 @@ cls_rule_set_nw_frag_masked(struct cls_rule *rule,
|
|||||||
void
|
void
|
||||||
cls_rule_set_icmp_type(struct cls_rule *rule, uint8_t icmp_type)
|
cls_rule_set_icmp_type(struct cls_rule *rule, uint8_t icmp_type)
|
||||||
{
|
{
|
||||||
rule->wc.wildcards &= ~FWW_TP_SRC;
|
cls_rule_set_tp_src(rule, htons(icmp_type));
|
||||||
rule->flow.tp_src = htons(icmp_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cls_rule_set_icmp_code(struct cls_rule *rule, uint8_t icmp_code)
|
cls_rule_set_icmp_code(struct cls_rule *rule, uint8_t icmp_code)
|
||||||
{
|
{
|
||||||
rule->wc.wildcards &= ~FWW_TP_DST;
|
cls_rule_set_tp_dst(rule, htons(icmp_code));
|
||||||
rule->flow.tp_dst = htons(icmp_code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -452,6 +462,23 @@ format_ipv6_netmask(struct ds *s, const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
format_be16_masked(struct ds *s, const char *name,
|
||||||
|
ovs_be16 value, ovs_be16 mask)
|
||||||
|
{
|
||||||
|
if (mask != htons(0)) {
|
||||||
|
ds_put_format(s, "%s=", name);
|
||||||
|
if (mask == htons(UINT16_MAX)) {
|
||||||
|
ds_put_format(s, "%"PRIu16, ntohs(value));
|
||||||
|
} else {
|
||||||
|
ds_put_format(s, "0x%"PRIx16"/0x%"PRIx16,
|
||||||
|
ntohs(value), ntohs(mask));
|
||||||
|
}
|
||||||
|
ds_put_char(s, ',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
||||||
{
|
{
|
||||||
@@ -464,7 +491,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
if (rule->priority != OFP_DEFAULT_PRIORITY) {
|
if (rule->priority != OFP_DEFAULT_PRIORITY) {
|
||||||
ds_put_format(s, "priority=%d,", rule->priority);
|
ds_put_format(s, "priority=%d,", rule->priority);
|
||||||
@@ -637,19 +664,11 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (f->nw_proto == IPPROTO_ICMP) {
|
if (f->nw_proto == IPPROTO_ICMP) {
|
||||||
if (!(w & FWW_TP_SRC)) {
|
format_be16_masked(s, "icmp_type", f->tp_src, wc->tp_src_mask);
|
||||||
ds_put_format(s, "icmp_type=%"PRIu16",", ntohs(f->tp_src));
|
format_be16_masked(s, "icmp_code", f->tp_dst, wc->tp_dst_mask);
|
||||||
}
|
|
||||||
if (!(w & FWW_TP_DST)) {
|
|
||||||
ds_put_format(s, "icmp_code=%"PRIu16",", ntohs(f->tp_dst));
|
|
||||||
}
|
|
||||||
} else if (f->nw_proto == IPPROTO_ICMPV6) {
|
} else if (f->nw_proto == IPPROTO_ICMPV6) {
|
||||||
if (!(w & FWW_TP_SRC)) {
|
format_be16_masked(s, "icmp_type", f->tp_src, wc->tp_src_mask);
|
||||||
ds_put_format(s, "icmp_type=%"PRIu16",", ntohs(f->tp_src));
|
format_be16_masked(s, "icmp_code", f->tp_dst, wc->tp_dst_mask);
|
||||||
}
|
|
||||||
if (!(w & FWW_TP_DST)) {
|
|
||||||
ds_put_format(s, "icmp_code=%"PRIu16",", ntohs(f->tp_dst));
|
|
||||||
}
|
|
||||||
if (!(w & FWW_ND_TARGET)) {
|
if (!(w & FWW_ND_TARGET)) {
|
||||||
ds_put_cstr(s, "nd_target=");
|
ds_put_cstr(s, "nd_target=");
|
||||||
print_ipv6_addr(s, &f->nd_target);
|
print_ipv6_addr(s, &f->nd_target);
|
||||||
@@ -664,12 +683,8 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
|||||||
ETH_ADDR_ARGS(f->arp_tha));
|
ETH_ADDR_ARGS(f->arp_tha));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(w & FWW_TP_SRC)) {
|
format_be16_masked(s, "tp_src", f->tp_src, wc->tp_src_mask);
|
||||||
ds_put_format(s, "tp_src=%"PRIu16",", ntohs(f->tp_src));
|
format_be16_masked(s, "tp_dst", f->tp_dst, wc->tp_dst_mask);
|
||||||
}
|
|
||||||
if (!(w & FWW_TP_DST)) {
|
|
||||||
ds_put_format(s, "tp_dst=%"PRIu16",", ntohs(f->tp_dst));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->length > start_len && ds_last(s) == ',') {
|
if (s->length > start_len && ds_last(s) == ',') {
|
||||||
@@ -1149,7 +1164,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
|
|||||||
const flow_wildcards_t wc = wildcards->wildcards;
|
const flow_wildcards_t wc = wildcards->wildcards;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||||
if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
|
if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
|
||||||
@@ -1163,8 +1178,8 @@ flow_equal_except(const struct flow *a, const struct flow *b,
|
|||||||
&& (wc & FWW_IN_PORT || a->in_port == b->in_port)
|
&& (wc & FWW_IN_PORT || a->in_port == b->in_port)
|
||||||
&& !((a->vlan_tci ^ b->vlan_tci) & wildcards->vlan_tci_mask)
|
&& !((a->vlan_tci ^ b->vlan_tci) & wildcards->vlan_tci_mask)
|
||||||
&& (wc & FWW_DL_TYPE || a->dl_type == b->dl_type)
|
&& (wc & FWW_DL_TYPE || a->dl_type == b->dl_type)
|
||||||
&& (wc & FWW_TP_SRC || a->tp_src == b->tp_src)
|
&& !((a->tp_src ^ b->tp_src) & wildcards->tp_src_mask)
|
||||||
&& (wc & FWW_TP_DST || a->tp_dst == b->tp_dst)
|
&& !((a->tp_dst ^ b->tp_dst) & wildcards->tp_dst_mask)
|
||||||
&& (wc & FWW_DL_SRC || eth_addr_equals(a->dl_src, b->dl_src))
|
&& (wc & FWW_DL_SRC || eth_addr_equals(a->dl_src, b->dl_src))
|
||||||
&& (wc & FWW_DL_DST
|
&& (wc & FWW_DL_DST
|
||||||
|| (!((a->dl_dst[0] ^ b->dl_dst[0]) & 0xfe)
|
|| (!((a->dl_dst[0] ^ b->dl_dst[0]) & 0xfe)
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
* Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -110,7 +110,11 @@ void cls_rule_set_dl_vlan(struct cls_rule *, ovs_be16);
|
|||||||
void cls_rule_set_any_pcp(struct cls_rule *);
|
void cls_rule_set_any_pcp(struct cls_rule *);
|
||||||
void cls_rule_set_dl_vlan_pcp(struct cls_rule *, uint8_t);
|
void cls_rule_set_dl_vlan_pcp(struct cls_rule *, uint8_t);
|
||||||
void cls_rule_set_tp_src(struct cls_rule *, ovs_be16);
|
void cls_rule_set_tp_src(struct cls_rule *, ovs_be16);
|
||||||
|
void cls_rule_set_tp_src_masked(struct cls_rule *,
|
||||||
|
ovs_be16 port, ovs_be16 mask);
|
||||||
void cls_rule_set_tp_dst(struct cls_rule *, ovs_be16);
|
void cls_rule_set_tp_dst(struct cls_rule *, ovs_be16);
|
||||||
|
void cls_rule_set_tp_dst_masked(struct cls_rule *,
|
||||||
|
ovs_be16 port, ovs_be16 mask);
|
||||||
void cls_rule_set_nw_proto(struct cls_rule *, uint8_t);
|
void cls_rule_set_nw_proto(struct cls_rule *, uint8_t);
|
||||||
void cls_rule_set_nw_src(struct cls_rule *, ovs_be32);
|
void cls_rule_set_nw_src(struct cls_rule *, ovs_be32);
|
||||||
void cls_rule_set_nw_src_masked(struct cls_rule *, ovs_be32 ip, ovs_be32 mask);
|
void cls_rule_set_nw_src_masked(struct cls_rule *, ovs_be32 ip, ovs_be32 mask);
|
||||||
|
44
lib/flow.c
44
lib/flow.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -444,7 +444,7 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
|
|||||||
const flow_wildcards_t wc = wildcards->wildcards;
|
const flow_wildcards_t wc = wildcards->wildcards;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||||
flow->regs[i] &= wildcards->reg_masks[i];
|
flow->regs[i] &= wildcards->reg_masks[i];
|
||||||
@@ -459,12 +459,8 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
|
|||||||
if (wc & FWW_DL_TYPE) {
|
if (wc & FWW_DL_TYPE) {
|
||||||
flow->dl_type = htons(0);
|
flow->dl_type = htons(0);
|
||||||
}
|
}
|
||||||
if (wc & FWW_TP_SRC) {
|
flow->tp_src &= wildcards->tp_src_mask;
|
||||||
flow->tp_src = htons(0);
|
flow->tp_dst &= wildcards->tp_dst_mask;
|
||||||
}
|
|
||||||
if (wc & FWW_TP_DST) {
|
|
||||||
flow->tp_dst = htons(0);
|
|
||||||
}
|
|
||||||
if (wc & FWW_DL_SRC) {
|
if (wc & FWW_DL_SRC) {
|
||||||
memset(flow->dl_src, 0, sizeof flow->dl_src);
|
memset(flow->dl_src, 0, sizeof flow->dl_src);
|
||||||
}
|
}
|
||||||
@@ -598,7 +594,7 @@ flow_print(FILE *stream, const struct flow *flow)
|
|||||||
void
|
void
|
||||||
flow_wildcards_init_catchall(struct flow_wildcards *wc)
|
flow_wildcards_init_catchall(struct flow_wildcards *wc)
|
||||||
{
|
{
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
wc->wildcards = FWW_ALL;
|
wc->wildcards = FWW_ALL;
|
||||||
wc->tun_id_mask = htonll(0);
|
wc->tun_id_mask = htonll(0);
|
||||||
@@ -609,6 +605,8 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
|
|||||||
memset(wc->reg_masks, 0, sizeof wc->reg_masks);
|
memset(wc->reg_masks, 0, sizeof wc->reg_masks);
|
||||||
wc->vlan_tci_mask = htons(0);
|
wc->vlan_tci_mask = htons(0);
|
||||||
wc->nw_frag_mask = 0;
|
wc->nw_frag_mask = 0;
|
||||||
|
wc->tp_src_mask = htons(0);
|
||||||
|
wc->tp_dst_mask = htons(0);
|
||||||
memset(wc->zeros, 0, sizeof wc->zeros);
|
memset(wc->zeros, 0, sizeof wc->zeros);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,7 +615,7 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
|
|||||||
void
|
void
|
||||||
flow_wildcards_init_exact(struct flow_wildcards *wc)
|
flow_wildcards_init_exact(struct flow_wildcards *wc)
|
||||||
{
|
{
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
wc->wildcards = 0;
|
wc->wildcards = 0;
|
||||||
wc->tun_id_mask = htonll(UINT64_MAX);
|
wc->tun_id_mask = htonll(UINT64_MAX);
|
||||||
@@ -628,6 +626,8 @@ flow_wildcards_init_exact(struct flow_wildcards *wc)
|
|||||||
memset(wc->reg_masks, 0xff, sizeof wc->reg_masks);
|
memset(wc->reg_masks, 0xff, sizeof wc->reg_masks);
|
||||||
wc->vlan_tci_mask = htons(UINT16_MAX);
|
wc->vlan_tci_mask = htons(UINT16_MAX);
|
||||||
wc->nw_frag_mask = UINT8_MAX;
|
wc->nw_frag_mask = UINT8_MAX;
|
||||||
|
wc->tp_src_mask = htons(UINT16_MAX);
|
||||||
|
wc->tp_dst_mask = htons(UINT16_MAX);
|
||||||
memset(wc->zeros, 0, sizeof wc->zeros);
|
memset(wc->zeros, 0, sizeof wc->zeros);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,12 +638,14 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
if (wc->wildcards
|
if (wc->wildcards
|
||||||
|| wc->tun_id_mask != htonll(UINT64_MAX)
|
|| wc->tun_id_mask != htonll(UINT64_MAX)
|
||||||
|| wc->nw_src_mask != htonl(UINT32_MAX)
|
|| wc->nw_src_mask != htonl(UINT32_MAX)
|
||||||
|| wc->nw_dst_mask != htonl(UINT32_MAX)
|
|| wc->nw_dst_mask != htonl(UINT32_MAX)
|
||||||
|
|| wc->tp_src_mask != htons(UINT16_MAX)
|
||||||
|
|| wc->tp_dst_mask != htons(UINT16_MAX)
|
||||||
|| wc->vlan_tci_mask != htons(UINT16_MAX)
|
|| wc->vlan_tci_mask != htons(UINT16_MAX)
|
||||||
|| !ipv6_mask_is_exact(&wc->ipv6_src_mask)
|
|| !ipv6_mask_is_exact(&wc->ipv6_src_mask)
|
||||||
|| !ipv6_mask_is_exact(&wc->ipv6_dst_mask)
|
|| !ipv6_mask_is_exact(&wc->ipv6_dst_mask)
|
||||||
@@ -667,12 +669,14 @@ flow_wildcards_is_catchall(const struct flow_wildcards *wc)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
if (wc->wildcards != FWW_ALL
|
if (wc->wildcards != FWW_ALL
|
||||||
|| wc->tun_id_mask != htonll(0)
|
|| wc->tun_id_mask != htonll(0)
|
||||||
|| wc->nw_src_mask != htonl(0)
|
|| wc->nw_src_mask != htonl(0)
|
||||||
|| wc->nw_dst_mask != htonl(0)
|
|| wc->nw_dst_mask != htonl(0)
|
||||||
|
|| wc->tp_src_mask != htons(0)
|
||||||
|
|| wc->tp_dst_mask != htons(0)
|
||||||
|| wc->vlan_tci_mask != htons(0)
|
|| wc->vlan_tci_mask != htons(0)
|
||||||
|| !ipv6_mask_is_any(&wc->ipv6_src_mask)
|
|| !ipv6_mask_is_any(&wc->ipv6_src_mask)
|
||||||
|| !ipv6_mask_is_any(&wc->ipv6_dst_mask)
|
|| !ipv6_mask_is_any(&wc->ipv6_dst_mask)
|
||||||
@@ -699,7 +703,7 @@ flow_wildcards_combine(struct flow_wildcards *dst,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
dst->wildcards = src1->wildcards | src2->wildcards;
|
dst->wildcards = src1->wildcards | src2->wildcards;
|
||||||
dst->tun_id_mask = src1->tun_id_mask & src2->tun_id_mask;
|
dst->tun_id_mask = src1->tun_id_mask & src2->tun_id_mask;
|
||||||
@@ -713,6 +717,8 @@ flow_wildcards_combine(struct flow_wildcards *dst,
|
|||||||
dst->reg_masks[i] = src1->reg_masks[i] & src2->reg_masks[i];
|
dst->reg_masks[i] = src1->reg_masks[i] & src2->reg_masks[i];
|
||||||
}
|
}
|
||||||
dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask;
|
dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask;
|
||||||
|
dst->tp_src_mask = src1->tp_src_mask & src2->tp_src_mask;
|
||||||
|
dst->tp_dst_mask = src1->tp_dst_mask & src2->tp_dst_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a hash of the wildcards in 'wc'. */
|
/* Returns a hash of the wildcards in 'wc'. */
|
||||||
@@ -734,7 +740,7 @@ flow_wildcards_equal(const struct flow_wildcards *a,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
if (a->wildcards != b->wildcards
|
if (a->wildcards != b->wildcards
|
||||||
|| a->tun_id_mask != b->tun_id_mask
|
|| a->tun_id_mask != b->tun_id_mask
|
||||||
@@ -742,7 +748,9 @@ flow_wildcards_equal(const struct flow_wildcards *a,
|
|||||||
|| a->nw_dst_mask != b->nw_dst_mask
|
|| a->nw_dst_mask != b->nw_dst_mask
|
||||||
|| a->vlan_tci_mask != b->vlan_tci_mask
|
|| a->vlan_tci_mask != b->vlan_tci_mask
|
||||||
|| !ipv6_addr_equals(&a->ipv6_src_mask, &b->ipv6_src_mask)
|
|| !ipv6_addr_equals(&a->ipv6_src_mask, &b->ipv6_src_mask)
|
||||||
|| !ipv6_addr_equals(&a->ipv6_dst_mask, &b->ipv6_dst_mask)) {
|
|| !ipv6_addr_equals(&a->ipv6_dst_mask, &b->ipv6_dst_mask)
|
||||||
|
|| a->tp_src_mask != b->tp_src_mask
|
||||||
|
|| a->tp_dst_mask != b->tp_dst_mask) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,7 +772,7 @@ flow_wildcards_has_extra(const struct flow_wildcards *a,
|
|||||||
int i;
|
int i;
|
||||||
struct in6_addr ipv6_masked;
|
struct in6_addr ipv6_masked;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||||
if ((a->reg_masks[i] & b->reg_masks[i]) != b->reg_masks[i]) {
|
if ((a->reg_masks[i] & b->reg_masks[i]) != b->reg_masks[i]) {
|
||||||
@@ -786,7 +794,9 @@ flow_wildcards_has_extra(const struct flow_wildcards *a,
|
|||||||
|| (a->tun_id_mask & b->tun_id_mask) != b->tun_id_mask
|
|| (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_src_mask & b->nw_src_mask) != b->nw_src_mask
|
||||||
|| (a->nw_dst_mask & b->nw_dst_mask) != b->nw_dst_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);
|
|| (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask
|
||||||
|
|| (a->tp_src_mask & b->tp_src_mask) != b->tp_src_mask
|
||||||
|
|| (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
|
/* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
|
||||||
|
22
lib/flow.h
22
lib/flow.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -35,7 +35,7 @@ struct ofpbuf;
|
|||||||
/* This sequence number should be incremented whenever anything involving flows
|
/* This sequence number should be incremented whenever anything involving flows
|
||||||
* or the wildcarding of flows changes. This will cause build assertion
|
* or the wildcarding of flows changes. This will cause build assertion
|
||||||
* failures in places which likely need to be updated. */
|
* failures in places which likely need to be updated. */
|
||||||
#define FLOW_WC_SEQ 7
|
#define FLOW_WC_SEQ 8
|
||||||
|
|
||||||
#define FLOW_N_REGS 5
|
#define FLOW_N_REGS 5
|
||||||
BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
|
BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
|
||||||
@@ -100,7 +100,7 @@ BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->nw_frag) == 1);
|
|||||||
BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
|
BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
|
||||||
|
|
||||||
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
|
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
|
||||||
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 130 && FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 130 && FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
|
void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
|
||||||
uint16_t in_port, struct flow *);
|
uint16_t in_port, struct flow *);
|
||||||
@@ -152,22 +152,20 @@ typedef unsigned int OVS_BITWISE flow_wildcards_t;
|
|||||||
/* excluding the multicast bit */
|
/* excluding the multicast bit */
|
||||||
#define FWW_DL_TYPE ((OVS_FORCE flow_wildcards_t) (1 << 4))
|
#define FWW_DL_TYPE ((OVS_FORCE flow_wildcards_t) (1 << 4))
|
||||||
#define FWW_NW_PROTO ((OVS_FORCE flow_wildcards_t) (1 << 5))
|
#define FWW_NW_PROTO ((OVS_FORCE flow_wildcards_t) (1 << 5))
|
||||||
#define FWW_TP_SRC ((OVS_FORCE flow_wildcards_t) (1 << 6))
|
|
||||||
#define FWW_TP_DST ((OVS_FORCE flow_wildcards_t) (1 << 7))
|
|
||||||
/* No corresponding OFPFW_* bits. */
|
/* No corresponding OFPFW_* bits. */
|
||||||
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 1))
|
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 1))
|
||||||
/* multicast bit only */
|
/* multicast bit only */
|
||||||
|
#define FWW_NW_DSCP ((OVS_FORCE flow_wildcards_t) (1 << 6))
|
||||||
|
#define FWW_NW_ECN ((OVS_FORCE flow_wildcards_t) (1 << 7))
|
||||||
#define FWW_ARP_SHA ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
#define FWW_ARP_SHA ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
||||||
#define FWW_ARP_THA ((OVS_FORCE flow_wildcards_t) (1 << 9))
|
#define FWW_ARP_THA ((OVS_FORCE flow_wildcards_t) (1 << 9))
|
||||||
#define FWW_ND_TARGET ((OVS_FORCE flow_wildcards_t) (1 << 10))
|
#define FWW_ND_TARGET ((OVS_FORCE flow_wildcards_t) (1 << 10))
|
||||||
#define FWW_IPV6_LABEL ((OVS_FORCE flow_wildcards_t) (1 << 11))
|
#define FWW_IPV6_LABEL ((OVS_FORCE flow_wildcards_t) (1 << 11))
|
||||||
#define FWW_NW_TTL ((OVS_FORCE flow_wildcards_t) (1 << 12))
|
#define FWW_NW_TTL ((OVS_FORCE flow_wildcards_t) (1 << 12))
|
||||||
#define FWW_NW_DSCP ((OVS_FORCE flow_wildcards_t) (1 << 13))
|
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 13)) - 1))
|
||||||
#define FWW_NW_ECN ((OVS_FORCE flow_wildcards_t) (1 << 14))
|
|
||||||
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 15)) - 1))
|
|
||||||
|
|
||||||
/* Remember to update FLOW_WC_SEQ when adding or removing FWW_*. */
|
/* Remember to update FLOW_WC_SEQ when adding or removing FWW_*. */
|
||||||
BUILD_ASSERT_DECL(FWW_ALL == ((1 << 15) - 1) && FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FWW_ALL == ((1 << 13) - 1) && FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
/* Information on wildcards for a flow, as a supplement to "struct flow".
|
/* Information on wildcards for a flow, as a supplement to "struct flow".
|
||||||
*
|
*
|
||||||
@@ -182,12 +180,14 @@ struct flow_wildcards {
|
|||||||
struct in6_addr ipv6_src_mask; /* 1-bit in each signficant ipv6_src bit. */
|
struct in6_addr ipv6_src_mask; /* 1-bit in each signficant ipv6_src bit. */
|
||||||
struct in6_addr ipv6_dst_mask; /* 1-bit in each signficant ipv6_dst bit. */
|
struct in6_addr ipv6_dst_mask; /* 1-bit in each signficant ipv6_dst bit. */
|
||||||
ovs_be16 vlan_tci_mask; /* 1-bit in each significant vlan_tci bit. */
|
ovs_be16 vlan_tci_mask; /* 1-bit in each significant vlan_tci bit. */
|
||||||
|
ovs_be16 tp_src_mask; /* 1-bit in each significant tp_src bit. */
|
||||||
|
ovs_be16 tp_dst_mask; /* 1-bit in each significant tp_dst bit. */
|
||||||
uint8_t nw_frag_mask; /* 1-bit in each significant nw_frag bit. */
|
uint8_t nw_frag_mask; /* 1-bit in each significant nw_frag bit. */
|
||||||
uint8_t zeros[5]; /* Padding field set to zero. */
|
uint8_t zeros[1]; /* Padding field set to zero. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */
|
/* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */
|
||||||
BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 80 && FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 80 && FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
void flow_wildcards_init_catchall(struct flow_wildcards *);
|
void flow_wildcards_init_catchall(struct flow_wildcards *);
|
||||||
void flow_wildcards_init_exact(struct flow_wildcards *);
|
void flow_wildcards_init_exact(struct flow_wildcards *);
|
||||||
|
@@ -290,7 +290,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
{
|
{
|
||||||
MFF_TCP_SRC, "tcp_src", "tp_src",
|
MFF_TCP_SRC, "tcp_src", "tp_src",
|
||||||
MF_FIELD_SIZES(be16),
|
MF_FIELD_SIZES(be16),
|
||||||
MFM_NONE, FWW_TP_SRC,
|
MFM_FULLY, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_TCP,
|
MFP_TCP,
|
||||||
true,
|
true,
|
||||||
@@ -298,7 +298,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
}, {
|
}, {
|
||||||
MFF_TCP_DST, "tcp_dst", "tp_dst",
|
MFF_TCP_DST, "tcp_dst", "tp_dst",
|
||||||
MF_FIELD_SIZES(be16),
|
MF_FIELD_SIZES(be16),
|
||||||
MFM_NONE, FWW_TP_DST,
|
MFM_FULLY, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_TCP,
|
MFP_TCP,
|
||||||
true,
|
true,
|
||||||
@@ -308,7 +308,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
{
|
{
|
||||||
MFF_UDP_SRC, "udp_src", NULL,
|
MFF_UDP_SRC, "udp_src", NULL,
|
||||||
MF_FIELD_SIZES(be16),
|
MF_FIELD_SIZES(be16),
|
||||||
MFM_NONE, FWW_TP_SRC,
|
MFM_FULLY, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_UDP,
|
MFP_UDP,
|
||||||
true,
|
true,
|
||||||
@@ -316,7 +316,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
}, {
|
}, {
|
||||||
MFF_UDP_DST, "udp_dst", NULL,
|
MFF_UDP_DST, "udp_dst", NULL,
|
||||||
MF_FIELD_SIZES(be16),
|
MF_FIELD_SIZES(be16),
|
||||||
MFM_NONE, FWW_TP_DST,
|
MFM_FULLY, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_UDP,
|
MFP_UDP,
|
||||||
true,
|
true,
|
||||||
@@ -326,7 +326,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
{
|
{
|
||||||
MFF_ICMPV4_TYPE, "icmp_type", NULL,
|
MFF_ICMPV4_TYPE, "icmp_type", NULL,
|
||||||
MF_FIELD_SIZES(u8),
|
MF_FIELD_SIZES(u8),
|
||||||
MFM_NONE, FWW_TP_SRC,
|
MFM_NONE, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_ICMPV4,
|
MFP_ICMPV4,
|
||||||
false,
|
false,
|
||||||
@@ -334,7 +334,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
}, {
|
}, {
|
||||||
MFF_ICMPV4_CODE, "icmp_code", NULL,
|
MFF_ICMPV4_CODE, "icmp_code", NULL,
|
||||||
MF_FIELD_SIZES(u8),
|
MF_FIELD_SIZES(u8),
|
||||||
MFM_NONE, FWW_TP_DST,
|
MFM_NONE, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_ICMPV4,
|
MFP_ICMPV4,
|
||||||
false,
|
false,
|
||||||
@@ -344,7 +344,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
{
|
{
|
||||||
MFF_ICMPV6_TYPE, "icmpv6_type", NULL,
|
MFF_ICMPV6_TYPE, "icmpv6_type", NULL,
|
||||||
MF_FIELD_SIZES(u8),
|
MF_FIELD_SIZES(u8),
|
||||||
MFM_NONE, FWW_TP_SRC,
|
MFM_NONE, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_ICMPV6,
|
MFP_ICMPV6,
|
||||||
false,
|
false,
|
||||||
@@ -352,7 +352,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
|
|||||||
}, {
|
}, {
|
||||||
MFF_ICMPV6_CODE, "icmpv6_code", NULL,
|
MFF_ICMPV6_CODE, "icmpv6_code", NULL,
|
||||||
MF_FIELD_SIZES(u8),
|
MF_FIELD_SIZES(u8),
|
||||||
MFM_NONE, FWW_TP_DST,
|
MFM_NONE, 0,
|
||||||
MFS_DECIMAL,
|
MFS_DECIMAL,
|
||||||
MFP_ICMPV6,
|
MFP_ICMPV6,
|
||||||
false,
|
false,
|
||||||
@@ -509,14 +509,6 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
|
|||||||
case MFF_ARP_OP:
|
case MFF_ARP_OP:
|
||||||
case MFF_ARP_SHA:
|
case MFF_ARP_SHA:
|
||||||
case MFF_ARP_THA:
|
case MFF_ARP_THA:
|
||||||
case MFF_TCP_SRC:
|
|
||||||
case MFF_TCP_DST:
|
|
||||||
case MFF_UDP_SRC:
|
|
||||||
case MFF_UDP_DST:
|
|
||||||
case MFF_ICMPV4_TYPE:
|
|
||||||
case MFF_ICMPV4_CODE:
|
|
||||||
case MFF_ICMPV6_TYPE:
|
|
||||||
case MFF_ICMPV6_CODE:
|
|
||||||
case MFF_ND_TARGET:
|
case MFF_ND_TARGET:
|
||||||
case MFF_ND_SLL:
|
case MFF_ND_SLL:
|
||||||
case MFF_ND_TLL:
|
case MFF_ND_TLL:
|
||||||
@@ -575,6 +567,17 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
|
|||||||
case MFF_ARP_TPA:
|
case MFF_ARP_TPA:
|
||||||
return !wc->nw_dst_mask;
|
return !wc->nw_dst_mask;
|
||||||
|
|
||||||
|
case MFF_TCP_SRC:
|
||||||
|
case MFF_UDP_SRC:
|
||||||
|
case MFF_ICMPV4_TYPE:
|
||||||
|
case MFF_ICMPV6_TYPE:
|
||||||
|
return !wc->tp_src_mask;
|
||||||
|
case MFF_TCP_DST:
|
||||||
|
case MFF_UDP_DST:
|
||||||
|
case MFF_ICMPV4_CODE:
|
||||||
|
case MFF_ICMPV6_CODE:
|
||||||
|
return !wc->tp_dst_mask;
|
||||||
|
|
||||||
case MFF_N_IDS:
|
case MFF_N_IDS:
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
@@ -603,14 +606,6 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
|
|||||||
case MFF_ARP_OP:
|
case MFF_ARP_OP:
|
||||||
case MFF_ARP_SHA:
|
case MFF_ARP_SHA:
|
||||||
case MFF_ARP_THA:
|
case MFF_ARP_THA:
|
||||||
case MFF_TCP_SRC:
|
|
||||||
case MFF_TCP_DST:
|
|
||||||
case MFF_UDP_SRC:
|
|
||||||
case MFF_UDP_DST:
|
|
||||||
case MFF_ICMPV4_TYPE:
|
|
||||||
case MFF_ICMPV4_CODE:
|
|
||||||
case MFF_ICMPV6_TYPE:
|
|
||||||
case MFF_ICMPV6_CODE:
|
|
||||||
case MFF_ND_TARGET:
|
case MFF_ND_TARGET:
|
||||||
case MFF_ND_SLL:
|
case MFF_ND_SLL:
|
||||||
case MFF_ND_TLL:
|
case MFF_ND_TLL:
|
||||||
@@ -683,6 +678,24 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
|
|||||||
mask->be32 = wc->nw_dst_mask;
|
mask->be32 = wc->nw_dst_mask;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MFF_TCP_SRC:
|
||||||
|
case MFF_UDP_SRC:
|
||||||
|
mask->be16 = wc->tp_src_mask;
|
||||||
|
break;
|
||||||
|
case MFF_TCP_DST:
|
||||||
|
case MFF_UDP_DST:
|
||||||
|
mask->be16 = wc->tp_dst_mask;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MFF_ICMPV4_TYPE:
|
||||||
|
case MFF_ICMPV6_TYPE:
|
||||||
|
mask->u8 = ntohs(wc->tp_src_mask);
|
||||||
|
break;
|
||||||
|
case MFF_ICMPV4_CODE:
|
||||||
|
case MFF_ICMPV6_CODE:
|
||||||
|
mask->u8 = ntohs(wc->tp_dst_mask);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_N_IDS:
|
case MFF_N_IDS:
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
@@ -1485,7 +1498,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
|
|||||||
case MFF_UDP_SRC:
|
case MFF_UDP_SRC:
|
||||||
case MFF_ICMPV4_TYPE:
|
case MFF_ICMPV4_TYPE:
|
||||||
case MFF_ICMPV6_TYPE:
|
case MFF_ICMPV6_TYPE:
|
||||||
rule->wc.wildcards |= FWW_TP_SRC;
|
rule->wc.tp_src_mask = htons(0);
|
||||||
rule->flow.tp_src = htons(0);
|
rule->flow.tp_src = htons(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1493,7 +1506,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
|
|||||||
case MFF_UDP_DST:
|
case MFF_UDP_DST:
|
||||||
case MFF_ICMPV4_CODE:
|
case MFF_ICMPV4_CODE:
|
||||||
case MFF_ICMPV6_CODE:
|
case MFF_ICMPV6_CODE:
|
||||||
rule->wc.wildcards |= FWW_TP_DST;
|
rule->wc.tp_dst_mask = htons(0);
|
||||||
rule->flow.tp_dst = htons(0);
|
rule->flow.tp_dst = htons(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1546,10 +1559,6 @@ mf_set(const struct mf_field *mf,
|
|||||||
case MFF_ARP_OP:
|
case MFF_ARP_OP:
|
||||||
case MFF_ARP_SHA:
|
case MFF_ARP_SHA:
|
||||||
case MFF_ARP_THA:
|
case MFF_ARP_THA:
|
||||||
case MFF_TCP_SRC:
|
|
||||||
case MFF_TCP_DST:
|
|
||||||
case MFF_UDP_SRC:
|
|
||||||
case MFF_UDP_DST:
|
|
||||||
case MFF_ICMPV4_TYPE:
|
case MFF_ICMPV4_TYPE:
|
||||||
case MFF_ICMPV4_CODE:
|
case MFF_ICMPV4_CODE:
|
||||||
case MFF_ICMPV6_TYPE:
|
case MFF_ICMPV6_TYPE:
|
||||||
@@ -1623,6 +1632,16 @@ mf_set(const struct mf_field *mf,
|
|||||||
cls_rule_set_nw_dst_masked(rule, value->be32, mask->be32);
|
cls_rule_set_nw_dst_masked(rule, value->be32, mask->be32);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MFF_TCP_SRC:
|
||||||
|
case MFF_UDP_SRC:
|
||||||
|
cls_rule_set_tp_src_masked(rule, value->be16, mask->be16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MFF_TCP_DST:
|
||||||
|
case MFF_UDP_DST:
|
||||||
|
cls_rule_set_tp_dst_masked(rule, value->be16, mask->be16);
|
||||||
|
break;
|
||||||
|
|
||||||
case MFF_N_IDS:
|
case MFF_N_IDS:
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
|
@@ -433,24 +433,16 @@ nxm_put_ip(struct ofpbuf *b, const struct cls_rule *cr,
|
|||||||
nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
|
nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
|
||||||
|
|
||||||
if (flow->nw_proto == IPPROTO_TCP) {
|
if (flow->nw_proto == IPPROTO_TCP) {
|
||||||
if (!(wc & FWW_TP_SRC)) {
|
nxm_put_16m(b, NXM_OF_TCP_SRC, flow->tp_src, cr->wc.tp_src_mask);
|
||||||
nxm_put_16(b, NXM_OF_TCP_SRC, flow->tp_src);
|
nxm_put_16m(b, NXM_OF_TCP_DST, flow->tp_dst, cr->wc.tp_dst_mask);
|
||||||
}
|
|
||||||
if (!(wc & FWW_TP_DST)) {
|
|
||||||
nxm_put_16(b, NXM_OF_TCP_DST, flow->tp_dst);
|
|
||||||
}
|
|
||||||
} else if (flow->nw_proto == IPPROTO_UDP) {
|
} else if (flow->nw_proto == IPPROTO_UDP) {
|
||||||
if (!(wc & FWW_TP_SRC)) {
|
nxm_put_16m(b, NXM_OF_UDP_SRC, flow->tp_src, cr->wc.tp_src_mask);
|
||||||
nxm_put_16(b, NXM_OF_UDP_SRC, flow->tp_src);
|
nxm_put_16m(b, NXM_OF_UDP_DST, flow->tp_dst, cr->wc.tp_dst_mask);
|
||||||
}
|
|
||||||
if (!(wc & FWW_TP_DST)) {
|
|
||||||
nxm_put_16(b, NXM_OF_UDP_DST, flow->tp_dst);
|
|
||||||
}
|
|
||||||
} else if (flow->nw_proto == icmp_proto) {
|
} else if (flow->nw_proto == icmp_proto) {
|
||||||
if (!(wc & FWW_TP_SRC)) {
|
if (cr->wc.tp_src_mask) {
|
||||||
nxm_put_8(b, icmp_type, ntohs(flow->tp_src));
|
nxm_put_8(b, icmp_type, ntohs(flow->tp_src));
|
||||||
}
|
}
|
||||||
if (!(wc & FWW_TP_DST)) {
|
if (cr->wc.tp_dst_mask) {
|
||||||
nxm_put_8(b, icmp_code, ntohs(flow->tp_dst));
|
nxm_put_8(b, icmp_code, ntohs(flow->tp_dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,7 +471,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr,
|
|||||||
int match_len;
|
int match_len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
/* Metadata. */
|
/* Metadata. */
|
||||||
if (!(wc & FWW_IN_PORT)) {
|
if (!(wc & FWW_IN_PORT)) {
|
||||||
|
@@ -78,9 +78,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
|
|||||||
WC_INVARIANT_BIT(DL_SRC) \
|
WC_INVARIANT_BIT(DL_SRC) \
|
||||||
WC_INVARIANT_BIT(DL_DST) \
|
WC_INVARIANT_BIT(DL_DST) \
|
||||||
WC_INVARIANT_BIT(DL_TYPE) \
|
WC_INVARIANT_BIT(DL_TYPE) \
|
||||||
WC_INVARIANT_BIT(NW_PROTO) \
|
WC_INVARIANT_BIT(NW_PROTO)
|
||||||
WC_INVARIANT_BIT(TP_SRC) \
|
|
||||||
WC_INVARIANT_BIT(TP_DST)
|
|
||||||
|
|
||||||
/* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
|
/* Verify that all of the invariant bits (as defined on WC_INVARIANT_LIST)
|
||||||
* actually have the same names and values. */
|
* actually have the same names and values. */
|
||||||
@@ -102,7 +100,7 @@ static const flow_wildcards_t WC_INVARIANTS = 0
|
|||||||
void
|
void
|
||||||
ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
|
ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
|
||||||
{
|
{
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
/* Initialize most of rule->wc. */
|
/* Initialize most of rule->wc. */
|
||||||
flow_wildcards_init_catchall(wc);
|
flow_wildcards_init_catchall(wc);
|
||||||
@@ -121,6 +119,13 @@ ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
|
|||||||
wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_SRC_SHIFT);
|
wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_SRC_SHIFT);
|
||||||
wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_DST_SHIFT);
|
wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_DST_SHIFT);
|
||||||
|
|
||||||
|
if (!(ofpfw & OFPFW_TP_SRC)) {
|
||||||
|
wc->tp_src_mask = htons(UINT16_MAX);
|
||||||
|
}
|
||||||
|
if (!(ofpfw & OFPFW_TP_DST)) {
|
||||||
|
wc->tp_dst_mask = htons(UINT16_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
if (ofpfw & OFPFW_DL_DST) {
|
if (ofpfw & OFPFW_DL_DST) {
|
||||||
/* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
|
/* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
|
||||||
* Open vSwitch breaks the Ethernet destination into bits as FWW_DL_DST
|
* Open vSwitch breaks the Ethernet destination into bits as FWW_DL_DST
|
||||||
@@ -200,6 +205,12 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
|
|||||||
if (wc->wildcards & FWW_NW_DSCP) {
|
if (wc->wildcards & FWW_NW_DSCP) {
|
||||||
ofpfw |= OFPFW_NW_TOS;
|
ofpfw |= OFPFW_NW_TOS;
|
||||||
}
|
}
|
||||||
|
if (!wc->tp_src_mask) {
|
||||||
|
ofpfw |= OFPFW_TP_SRC;
|
||||||
|
}
|
||||||
|
if (!wc->tp_dst_mask) {
|
||||||
|
ofpfw |= OFPFW_TP_DST;
|
||||||
|
}
|
||||||
|
|
||||||
/* Translate VLANs. */
|
/* Translate VLANs. */
|
||||||
match->dl_vlan = htons(0);
|
match->dl_vlan = htons(0);
|
||||||
@@ -905,7 +916,7 @@ ofputil_min_flow_format(const struct cls_rule *rule)
|
|||||||
{
|
{
|
||||||
const struct flow_wildcards *wc = &rule->wc;
|
const struct flow_wildcards *wc = &rule->wc;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 7);
|
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 8);
|
||||||
|
|
||||||
/* Only NXM supports separately wildcards the Ethernet multicast bit. */
|
/* Only NXM supports separately wildcards the Ethernet multicast bit. */
|
||||||
if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
|
if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
|
||||||
@@ -953,6 +964,12 @@ ofputil_min_flow_format(const struct cls_rule *rule)
|
|||||||
return NXFF_NXM;
|
return NXFF_NXM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only NXM supports bitwise matching on transport port. */
|
||||||
|
if ((wc->tp_src_mask && wc->tp_src_mask != htons(UINT16_MAX)) ||
|
||||||
|
(wc->tp_dst_mask && wc->tp_dst_mask != htons(UINT16_MAX))) {
|
||||||
|
return NXFF_NXM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Other formats can express this rule. */
|
/* Other formats can express this rule. */
|
||||||
return NXFF_OPENFLOW10;
|
return NXFF_OPENFLOW10;
|
||||||
}
|
}
|
||||||
@@ -2735,7 +2752,7 @@ ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
|
|||||||
wc.nw_src_mask = wc.nw_dst_mask = htonl(0);
|
wc.nw_src_mask = wc.nw_dst_mask = htonl(0);
|
||||||
}
|
}
|
||||||
if (!(may_match & MAY_TP_ADDR)) {
|
if (!(may_match & MAY_TP_ADDR)) {
|
||||||
wc.wildcards |= FWW_TP_SRC | FWW_TP_DST;
|
wc.tp_src_mask = wc.tp_dst_mask = htons(0);
|
||||||
}
|
}
|
||||||
if (!(may_match & MAY_NW_PROTO)) {
|
if (!(may_match & MAY_NW_PROTO)) {
|
||||||
wc.wildcards |= FWW_NW_PROTO;
|
wc.wildcards |= FWW_NW_PROTO;
|
||||||
|
@@ -10,7 +10,7 @@ tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
|||||||
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
||||||
cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
|
cookie=0x123456789abcdef hard_timeout=10 priority=60000 actions=controller
|
||||||
actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
|
actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note
|
||||||
tun_id=0x1234,cookie=0x5678,actions=flood
|
tcp,tp_src=0x1230/0xfff0,tun_id=0x1234,cookie=0x5678,actions=flood
|
||||||
actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel:0x123456789
|
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=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])
|
||||||
table=1,actions=drop
|
table=1,actions=drop
|
||||||
@@ -40,7 +40,7 @@ OFPT_FLOW_MOD: ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
|||||||
OFPT_FLOW_MOD: ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
|
OFPT_FLOW_MOD: ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535
|
||||||
OFPT_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
|
OFPT_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_SET_FLOW_FORMAT: format=nxm
|
NXT_SET_FLOW_FORMAT: format=nxm
|
||||||
NXT_FLOW_MOD: ADD tun_id=0x1234 cookie:0x5678 actions=FLOOD
|
NXT_FLOW_MOD: ADD tcp,tun_id=0x1234,tp_src=0x1230/0xfff0 cookie:0x5678 actions=FLOOD
|
||||||
NXT_FLOW_MOD: ADD actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel64:0x123456789
|
NXT_FLOW_MOD: ADD actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel64:0x123456789
|
||||||
NXT_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])
|
NXT_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])
|
||||||
NXT_FLOW_MOD_TABLE_ID: enable
|
NXT_FLOW_MOD_TABLE_ID: enable
|
||||||
@@ -243,18 +243,22 @@ NXM_OF_ETH_TYPE(0806) NXM_OF_IP_DST_W(C0D80000/FFFF0000)
|
|||||||
|
|
||||||
# TCP source port
|
# TCP source port
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_SRC(4231)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_SRC(4231)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_SRC_W(5050/F0F0)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(07) NXM_OF_TCP_SRC(4231)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(07) NXM_OF_TCP_SRC(4231)
|
||||||
|
|
||||||
# TCP destination port
|
# TCP destination port
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_DST(4231)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_DST(4231)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_TCP_DST_W(FDE0/FFF0)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(07) NXM_OF_TCP_DST(4231)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(07) NXM_OF_TCP_DST(4231)
|
||||||
|
|
||||||
# UDP source port
|
# UDP source port
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_SRC(8732)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_SRC(8732)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_SRC_W(0132/01FF)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_UDP_SRC(7823)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(06) NXM_OF_UDP_SRC(7823)
|
||||||
|
|
||||||
# UDP destination port
|
# UDP destination port
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_DST(1782)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_DST(1782)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(11) NXM_OF_UDP_DST_W(5005/F00F)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(02) NXM_OF_UDP_DST(1293)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_IP_PROTO(02) NXM_OF_UDP_DST(1293)
|
||||||
|
|
||||||
# ICMP type
|
# ICMP type
|
||||||
@@ -436,18 +440,22 @@ nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
|||||||
|
|
||||||
# TCP source port
|
# TCP source port
|
||||||
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_SRC(4231)
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_SRC(4231)
|
||||||
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_SRC_W(5050/f0f0)
|
||||||
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
||||||
|
|
||||||
# TCP destination port
|
# TCP destination port
|
||||||
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_DST(4231)
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_DST(4231)
|
||||||
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_DST_W(fde0/fff0)
|
||||||
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
||||||
|
|
||||||
# UDP source port
|
# UDP source port
|
||||||
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_SRC(8732)
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_SRC(8732)
|
||||||
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_SRC_W(0132/01ff)
|
||||||
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
||||||
|
|
||||||
# UDP destination port
|
# UDP destination port
|
||||||
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_DST(1782)
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_DST(1782)
|
||||||
|
NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(11), NXM_OF_UDP_DST_W(5005/f00f)
|
||||||
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
nx_pull_match() returned error NXBRC_NXM_BAD_PREREQ
|
||||||
|
|
||||||
# ICMP type
|
# ICMP type
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
* Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -50,8 +50,8 @@
|
|||||||
CLS_FIELD(FWW_IN_PORT, in_port, IN_PORT) \
|
CLS_FIELD(FWW_IN_PORT, in_port, IN_PORT) \
|
||||||
CLS_FIELD(0, vlan_tci, VLAN_TCI) \
|
CLS_FIELD(0, vlan_tci, VLAN_TCI) \
|
||||||
CLS_FIELD(FWW_DL_TYPE, dl_type, DL_TYPE) \
|
CLS_FIELD(FWW_DL_TYPE, dl_type, DL_TYPE) \
|
||||||
CLS_FIELD(FWW_TP_SRC, tp_src, TP_SRC) \
|
CLS_FIELD(0, tp_src, TP_SRC) \
|
||||||
CLS_FIELD(FWW_TP_DST, tp_dst, TP_DST) \
|
CLS_FIELD(0, tp_dst, TP_DST) \
|
||||||
CLS_FIELD(FWW_DL_SRC, dl_src, DL_SRC) \
|
CLS_FIELD(FWW_DL_SRC, dl_src, DL_SRC) \
|
||||||
CLS_FIELD(FWW_DL_DST | FWW_ETH_MCAST, dl_dst, DL_DST) \
|
CLS_FIELD(FWW_DL_DST | FWW_ETH_MCAST, dl_dst, DL_DST) \
|
||||||
CLS_FIELD(FWW_NW_PROTO, nw_proto, NW_PROTO) \
|
CLS_FIELD(FWW_NW_PROTO, nw_proto, NW_PROTO) \
|
||||||
@@ -198,6 +198,10 @@ match(const struct cls_rule *wild, const struct flow *fixed)
|
|||||||
eq = !((fixed->nw_src ^ wild->flow.nw_src) & wild->wc.nw_src_mask);
|
eq = !((fixed->nw_src ^ wild->flow.nw_src) & wild->wc.nw_src_mask);
|
||||||
} else if (f_idx == CLS_F_IDX_NW_DST) {
|
} else if (f_idx == CLS_F_IDX_NW_DST) {
|
||||||
eq = !((fixed->nw_dst ^ wild->flow.nw_dst) & wild->wc.nw_dst_mask);
|
eq = !((fixed->nw_dst ^ wild->flow.nw_dst) & wild->wc.nw_dst_mask);
|
||||||
|
} else if (f_idx == CLS_F_IDX_TP_SRC) {
|
||||||
|
eq = !((fixed->tp_src ^ wild->flow.tp_src) & wild->wc.tp_src_mask);
|
||||||
|
} else if (f_idx == CLS_F_IDX_TP_DST) {
|
||||||
|
eq = !((fixed->tp_dst ^ wild->flow.tp_dst) & wild->wc.tp_dst_mask);
|
||||||
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
||||||
eq = !((fixed->vlan_tci ^ wild->flow.vlan_tci)
|
eq = !((fixed->vlan_tci ^ wild->flow.vlan_tci)
|
||||||
& wild->wc.vlan_tci_mask);
|
& wild->wc.vlan_tci_mask);
|
||||||
@@ -463,6 +467,10 @@ make_rule(int wc_fields, unsigned int priority, int value_pat)
|
|||||||
rule->cls_rule.wc.nw_src_mask = htonl(UINT32_MAX);
|
rule->cls_rule.wc.nw_src_mask = htonl(UINT32_MAX);
|
||||||
} else if (f_idx == CLS_F_IDX_NW_DST) {
|
} else if (f_idx == CLS_F_IDX_NW_DST) {
|
||||||
rule->cls_rule.wc.nw_dst_mask = htonl(UINT32_MAX);
|
rule->cls_rule.wc.nw_dst_mask = htonl(UINT32_MAX);
|
||||||
|
} else if (f_idx == CLS_F_IDX_TP_SRC) {
|
||||||
|
rule->cls_rule.wc.tp_src_mask = htons(UINT16_MAX);
|
||||||
|
} else if (f_idx == CLS_F_IDX_TP_DST) {
|
||||||
|
rule->cls_rule.wc.tp_dst_mask = htons(UINT16_MAX);
|
||||||
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
} else if (f_idx == CLS_F_IDX_VLAN_TCI) {
|
||||||
rule->cls_rule.wc.vlan_tci_mask = htons(UINT16_MAX);
|
rule->cls_rule.wc.vlan_tci_mask = htons(UINT16_MAX);
|
||||||
} else if (f_idx == CLS_F_IDX_TUN_ID) {
|
} else if (f_idx == CLS_F_IDX_TUN_ID) {
|
||||||
|
@@ -443,13 +443,75 @@ above).
|
|||||||
.IQ \fBtp_dst=\fIport\fR
|
.IQ \fBtp_dst=\fIport\fR
|
||||||
When \fBdl_type\fR and \fBnw_proto\fR specify TCP or UDP, \fBtp_src\fR
|
When \fBdl_type\fR and \fBnw_proto\fR specify TCP or UDP, \fBtp_src\fR
|
||||||
and \fBtp_dst\fR match the UDP or TCP source or destination port
|
and \fBtp_dst\fR match the UDP or TCP source or destination port
|
||||||
\fIport\fR, respectively. which is specified as a decimal number
|
\fIport\fR, respectively, which is specified as a decimal number
|
||||||
between 0 and 65535, inclusive (e.g. 80 to match packets originating
|
between 0 and 65535, inclusive (e.g. 80 to match packets originating
|
||||||
from a HTTP server).
|
from a HTTP server).
|
||||||
.IP
|
.IP
|
||||||
When \fBdl_type\fR and \fBnw_proto\fR take other values, the values of
|
When \fBdl_type\fR and \fBnw_proto\fR take other values, the values of
|
||||||
these settings are ignored (see \fBFlow Syntax\fR above).
|
these settings are ignored (see \fBFlow Syntax\fR above).
|
||||||
.
|
.
|
||||||
|
.IP \fBtp_src=\fIport\fB/\fImask\fR
|
||||||
|
.IQ \fBtp_dst=\fIport\fB/\fImask\fR
|
||||||
|
Bitwise match on TCP (or UDP) source or destination port,
|
||||||
|
respectively. The \fIport\fR and \fImask\fR are 16-bit numbers
|
||||||
|
written in decimal or in hexadecimal prefixed by \fB0x\fR. Each 1-bit
|
||||||
|
in \fImask\fR requires that the corresponding bit in \fIport\fR must
|
||||||
|
match. Each 0-bit in \fImask\fR causes the corresponding bit to be
|
||||||
|
ignored.
|
||||||
|
.IP
|
||||||
|
Bitwise matches on transport ports are rarely useful in isolation, but
|
||||||
|
a group of them can be used to reduce the number of flows required to
|
||||||
|
match on a range of transport ports. For example, suppose that the
|
||||||
|
goal is to match TCP source ports 1000 to 1999, inclusive. One way is
|
||||||
|
to insert 1001 flows, each of which matches on a single source port.
|
||||||
|
Another way is to look at the binary representations of 1000 and 1999,
|
||||||
|
as follows:
|
||||||
|
.br
|
||||||
|
.B "01111101000"
|
||||||
|
.br
|
||||||
|
.B "11111001111"
|
||||||
|
.br
|
||||||
|
and then to transform those into a series of bitwise matches that
|
||||||
|
accomplish the same results:
|
||||||
|
.br
|
||||||
|
.B "01111101xxx"
|
||||||
|
.br
|
||||||
|
.B "0111111xxxx"
|
||||||
|
.br
|
||||||
|
.B "10xxxxxxxxx"
|
||||||
|
.br
|
||||||
|
.B "110xxxxxxxx"
|
||||||
|
.br
|
||||||
|
.B "1110xxxxxxx"
|
||||||
|
.br
|
||||||
|
.B "11110xxxxxx"
|
||||||
|
.br
|
||||||
|
.B "1111100xxxx"
|
||||||
|
.br
|
||||||
|
which become the following when written in the syntax required by
|
||||||
|
\fBovs\-ofctl\fR:
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x03e8/0xfff8"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x03f0/0xfff0"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x0400/0xfe00"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x0600/0xff00"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x0700/0xff80"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x0780/0xffc0"
|
||||||
|
.br
|
||||||
|
.B "tcp,tp_src=0x07c0/0xfff0"
|
||||||
|
.IP
|
||||||
|
Only Open vSwitch 1.6 and later supports bitwise matching on transport
|
||||||
|
ports.
|
||||||
|
.IP
|
||||||
|
Like the exact-match forms of \fBtp_src\fR and \fBtp_dst\fR described
|
||||||
|
above, the bitwise match forms apply only when When \fBdl_type\fR and
|
||||||
|
\fBnw_proto\fR specify TCP or UDP.
|
||||||
|
.
|
||||||
.IP \fBicmp_type=\fItype\fR
|
.IP \fBicmp_type=\fItype\fR
|
||||||
.IQ \fBicmp_code=\fIcode\fR
|
.IQ \fBicmp_code=\fIcode\fR
|
||||||
When \fBdl_type\fR and \fBnw_proto\fR specify ICMP or ICMPv6, \fItype\fR
|
When \fBdl_type\fR and \fBnw_proto\fR specify ICMP or ICMPv6, \fItype\fR
|
||||||
|
Reference in New Issue
Block a user