Hi all
I'm trying to add a new action to set or reduce TCP window size and I wrote the
patch below but I could not see my new action in action set, please could
someone help me figuring the problem out.
Thanks in advance..
- Volkan
argela@avatli:~/workspace/ovs$ ovs-ofctl add-flow s1 -O OpenFlow13
in_port=2,tcp,nw_src=10.1.1.20,nw_dst=10.1.1.10,tcp_flags=ack,action=set_rwnd:50,output:1
argela@avatli:~/workspace/ovs$ ovs-ofctl dump-flows s1 -O OpenFlow13
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x0, duration=3.030s, table=0, n_packets=0, n_bytes=0,
tcp,in_port=2,nw_src=10.1.1.20,nw_dst=10.1.1.10,tcp_flags=ack
actions=set_rwnd:50,output:1
$$$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: datapath/actions.c
modified: datapath/linux/compat/include/linux/openvswitch.h
modified: include/openvswitch/flow.h
modified: include/openvswitch/ofp-actions.h
modified: lib/dpif-netdev.c
modified: lib/dpif.c
modified: lib/odp-execute.c
modified: lib/odp-util.c
modified: lib/ofp-actions.c
modified: ofproto/ofproto-dpif-xlate.c
Untracked files:
(use "git add <file>..." to include in what will be committed)
.cproject
.project
no changes added to commit (use "git add" and/or "git commit -a")
$$$ git diff
diff --git a/datapath/actions.c b/datapath/actions.c
index 82833d0..675c53a 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -1164,6 +1164,11 @@ static int do_execute_actions(struct datapath *dp,
struct sk_buff *skb,
err = sample(dp, skb, key, a, attr, len);
break;
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
+ printf("OVS_ACTION_ATTR_SET_RWND\n");
+ break;
+
case OVS_ACTION_ATTR_CT:
if (!is_flow_key_valid(key)) {
err = ovs_flow_key_update(skb, key);
diff --git a/datapath/linux/compat/include/linux/openvswitch.h
b/datapath/linux/compat/include/linux/openvswitch.h
index 12260d8..803e455 100644
--- a/datapath/linux/compat/include/linux/openvswitch.h
+++ b/datapath/linux/compat/include/linux/openvswitch.h
@@ -815,6 +815,9 @@ enum ovs_action_attr {
OVS_ACTION_ATTR_CT, /* Nested OVS_CT_ATTR_* . */
OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */
+ OVS_ACTION_ATTR_REDUCE_RWND,
+ OVS_ACTION_ATTR_SET_RWND,
+
#ifndef __KERNEL__
OVS_ACTION_ATTR_TUNNEL_PUSH, /* struct ovs_action_push_tnl*/
OVS_ACTION_ATTR_TUNNEL_POP, /* u32 port number. */
diff --git a/include/openvswitch/flow.h b/include/openvswitch/flow.h
index df80dfe..64da205 100644
--- a/include/openvswitch/flow.h
+++ b/include/openvswitch/flow.h
@@ -120,7 +120,9 @@ struct flow {
struct eth_addr arp_sha; /* ARP/ND source hardware address. */
struct eth_addr arp_tha; /* ARP/ND target hardware address. */
ovs_be16 tcp_flags; /* TCP flags. With L3 to avoid matching L4. */
- ovs_be16 pad3; /* Pad to 64 bits. */
+ ovs_be16 rwnd;
+ uint8_t rate;
+ uint8_t pad3[7]; /* Pad to 64 bits. */
/* L4 (64-bit aligned) */
ovs_be16 tp_src; /* TCP/UDP/SCTP source port/ICMP type. */
@@ -135,7 +137,7 @@ BUILD_ASSERT_DECL(sizeof(struct flow_tnl) %
sizeof(uint64_t) == 0);
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
BUILD_ASSERT_DECL(offsetof(struct flow, igmp_group_ip4) + sizeof(uint32_t)
- == sizeof(struct flow_tnl) + 248
+ == sizeof(struct flow_tnl) + 256
&& FLOW_WC_SEQ == 36);
/* Incremental points at which flow classification may be performed in
diff --git a/include/openvswitch/ofp-actions.h
b/include/openvswitch/ofp-actions.h
index 74e9dcc..a7512e5 100644
--- a/include/openvswitch/ofp-actions.h
+++ b/include/openvswitch/ofp-actions.h
@@ -86,6 +86,8 @@
OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \
OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \
OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \
+ OFPACT(REDUCE_RWND, ofpact_reduce_rwnd, ofpact, "reduce_rwnd") \
+ OFPACT(SET_RWND, ofpact_set_rwnd, ofpact, "set_rwnd") \
\
/* Metadata. */ \
OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \
@@ -426,6 +428,16 @@ struct ofpact_ip_ttl {
uint8_t ttl;
};
+struct ofpact_reduce_rwnd {
+ struct ofpact ofpact;
+ uint8_t rate;
+};
+
+struct ofpact_set_rwnd {
+ struct ofpact ofpact;
+ uint16_t rwnd;
+};
+
/* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT.
*
* Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 1400511..fd7dd64 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -4603,6 +4603,8 @@ dp_execute_cb(void *aux_, struct dp_packet_batch
*packets_,
case OVS_ACTION_ATTR_POP_MPLS:
case OVS_ACTION_ATTR_SET:
case OVS_ACTION_ATTR_SET_MASKED:
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_HASH:
case OVS_ACTION_ATTR_UNSPEC:
diff --git a/lib/dpif.c b/lib/dpif.c
index 53958c5..6cb033b 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1186,6 +1186,8 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch
*packets_,
case OVS_ACTION_ATTR_SET_MASKED:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_TRUNC:
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
OVS_NOT_REACHED();
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 65a6fcd..a120aab 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -504,6 +504,8 @@ requires_datapath_assistance(const struct nlattr *a)
case OVS_ACTION_ATTR_PUSH_MPLS:
case OVS_ACTION_ATTR_POP_MPLS:
case OVS_ACTION_ATTR_TRUNC:
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
return false;
case OVS_ACTION_ATTR_UNSPEC:
@@ -613,6 +615,11 @@ odp_execute_actions(void *dp, struct dp_packet_batch
*batch, bool steal,
}
break;
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
+ printf("OVS_ACTION_ATTR_SET_RWND odp_execute\n");
+ break;
+
case OVS_ACTION_ATTR_SAMPLE:
for (i = 0; i < cnt; i++) {
odp_execute_sample(dp, packets[i], steal && last_action, a,
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 626a82c..8d5b8c2 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -121,6 +121,8 @@ odp_action_len(uint16_t type)
case OVS_ACTION_ATTR_SET_MASKED: return ATTR_LEN_VARIABLE;
case OVS_ACTION_ATTR_SAMPLE: return ATTR_LEN_VARIABLE;
case OVS_ACTION_ATTR_CT: return ATTR_LEN_VARIABLE;
+ case OVS_ACTION_ATTR_REDUCE_RWND: return sizeof(ovs_be16);
+ case OVS_ACTION_ATTR_SET_RWND: return sizeof(ovs_be16);
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
@@ -859,6 +861,10 @@ format_odp_action(struct ds *ds, const struct nlattr *a)
case OVS_ACTION_ATTR_CT:
format_odp_conntrack_action(ds, a);
break;
+ case OVS_ACTION_ATTR_REDUCE_RWND:
+ case OVS_ACTION_ATTR_SET_RWND:
+ printf("format-odp-ac\n");
+ break;
case OVS_ACTION_ATTR_UNSPEC:
case __OVS_ACTION_ATTR_MAX:
default:
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 16f0f7c..a7da17e 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -229,6 +229,11 @@ enum ofp_raw_action_type {
/* NX1.0-1.4(6): struct nx_action_reg_move, ... */
NXAST_RAW_REG_MOVE,
+ /* OF1.3+(41): uint8_t. */
+ OFPAT_RAW_REDUCE_RWND,
+ /* OF1.3+(42): uint16_t. */
+ OFPAT_RAW_SET_RWND,
+
/* ## ------------------------- ## */
/* ## Nicira extension actions. ## */
/* ## ------------------------- ## */
@@ -431,6 +436,8 @@ ofpact_next_flattened(const struct ofpact *ofpact)
case OFPACT_WRITE_METADATA:
case OFPACT_GOTO_TABLE:
case OFPACT_NAT:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
return ofpact_next(ofpact);
case OFPACT_CT:
@@ -1995,6 +2002,18 @@ format_SET_IP_TTL(const struct ofpact_ip_ttl *a, struct
ds *s)
{
ds_put_format(s, "%smod_nw_ttl:%s%d", colors.param, colors.end, a->ttl);
}
+
+static void
+format_REDUCE_RWND(const struct ofpact_reduce_rwnd *a, struct ds *s)
+{
+ ds_put_format(s, "%sreduce_rwnd:%s%d", colors.param, colors.end, a->rate);
+}
+
+static void
+format_SET_RWND(const struct ofpact_set_rwnd *a, struct ds *s)
+{
+ ds_put_format(s, "%sset_rwnd:%s%d", colors.param, colors.end, a->rwnd);
+}
^L
/* Set TCP/UDP/SCTP port actions. */
@@ -2016,6 +2035,24 @@ decode_OFPAT_RAW_SET_TP_DST(ovs_be16 port,
return 0;
}
+static enum ofperr
+decode_OFPAT_RAW_REDUCE_RWND(uint8_t rate,
+ enum ofp_version ofp_version OVS_UNUSED,
+ struct ofpbuf *out)
+{
+ ofpact_put_REDUCE_RWND(out)->rate = rate;
+ return 0;
+}
+
+static enum ofperr
+decode_OFPAT_RAW_SET_RWND(uint16_t rwnd,
+ enum ofp_version ofp_version OVS_UNUSED,
+ struct ofpbuf *out)
+{
+ ofpact_put_SET_RWND(out)->rwnd = ntohs(rwnd);
+ return 0;
+}
+
static void
encode_SET_L4_port(const struct ofpact_l4_port *l4_port,
enum ofp_version ofp_version, enum ofp_raw_action_type raw,
@@ -2057,6 +2094,20 @@ encode_SET_L4_DST_PORT(const struct ofpact_l4_port
*l4_port,
encode_SET_L4_port(l4_port, ofp_version, OFPAT_RAW_SET_TP_DST, field, out);
}
+static void
+encode_REDUCE_RWND(const struct ofpact_reduce_rwnd *reduce_rwnd,
+ enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+ put_OFPAT_REDUCE_RWND(out, reduce_rwnd->rate);
+}
+
+static void
+encode_SET_RWND(const struct ofpact_set_rwnd *set_rwnd,
+ enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+ put_OFPAT_SET_RWND(out, set_rwnd->rwnd);
+}
+
static char * OVS_WARN_UNUSED_RESULT
parse_SET_L4_SRC_PORT(char *arg, struct ofpbuf *ofpacts,
enum ofputil_protocol *usable_protocols OVS_UNUSED)
@@ -2084,6 +2135,39 @@ format_SET_L4_DST_PORT(const struct ofpact_l4_port *a,
struct ds *s)
{
ds_put_format(s, "%smod_tp_dst:%s%d", colors.param, colors.end, a->port);
}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_SET_RWND(char *arg, struct ofpbuf *ofpacts,
+ enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+ uint16_t rwnd;
+ char *error;
+
+ error = str_to_u16(arg, "rwnd", &rwnd);
+ if (error) {
+ return error;
+ }
+
+ ofpact_put_SET_RWND(ofpacts)->rwnd = rwnd;
+ return NULL;
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_REDUCE_RWND(char *arg, struct ofpbuf *ofpacts,
+ enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+ uint8_t rate;
+ char *error;
+
+ error = str_to_u8(arg, "rate", &rate);
+ if (error) {
+ return error;
+ }
+
+ ofpact_put_REDUCE_RWND(ofpacts)->rate = rate;
+ return NULL;
+}
+
^L
/* Action structure for OFPAT_COPY_FIELD. */
struct ofp15_action_copy_field {
@@ -6156,6 +6240,8 @@ ofpact_is_set_or_move_action(const struct ofpact *a)
case OFPACT_SET_TUNNEL:
case OFPACT_SET_VLAN_PCP:
case OFPACT_SET_VLAN_VID:
+ case OFPACT_SET_RWND:
+ case OFPACT_REDUCE_RWND:
return true;
case OFPACT_BUNDLE:
case OFPACT_CLEAR_ACTIONS:
@@ -6229,6 +6315,8 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
case OFPACT_SET_VLAN_PCP:
case OFPACT_SET_VLAN_VID:
case OFPACT_STRIP_VLAN:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
return true;
/* In general these actions are excluded because they are not part of
@@ -6472,6 +6560,8 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type
type)
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
default:
return OVSINST_OFPIT11_APPLY_ACTIONS;
}
@@ -6920,7 +7010,13 @@ ofpact_check__(enum ofputil_protocol *usable_protocols,
struct ofpact *a,
inconsistent_match(usable_protocols);
}
return 0;
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
+ if (!is_ip_any(flow) || (flow->nw_proto != IPPROTO_TCP)) {
+ inconsistent_match(usable_protocols);
+ }
+ return 0;
case OFPACT_SET_IP_DSCP:
case OFPACT_SET_IP_ECN:
case OFPACT_SET_IP_TTL:
@@ -7457,6 +7553,9 @@ get_ofpact_map(enum ofp_version version)
{ OFPACT_SET_IP_TTL, 23 },
{ OFPACT_DEC_TTL, 24 },
{ OFPACT_SET_FIELD, 25 },
+
+ { OFPACT_REDUCE_RWND, 41 },
+ { OFPACT_SET_RWND, 42 },
/* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
/* OF1.3+ OFPAT_POP_PBB (27) not supported. */
{ 0, -1 },
@@ -7590,6 +7689,8 @@ ofpact_outputs_to_port(const struct ofpact *ofpact,
ofp_port_t port)
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
default:
return false;
}
@@ -7824,7 +7925,12 @@ ofpacts_parse__(char *str, struct ofpbuf *ofpacts,
return xstrdup("apply_actions is the default instruction");
} else if (ofputil_port_from_string(key, &port)) {
ofpact_put_OUTPUT(ofpacts)->port = port;
- } else {
+
+ } /*else if (!strcasecmp(key, "reduce_rwnd")) {
+ error = parse_REDUCE_RWND(value, ofpacts, usable_protocols);
+ } else if (!strcasecmp(key, "set_rwnd")) {
+ error = parse_SET_RWND(value, ofpacts, usable_protocols);
+ } */ else {
return xasprintf("unknown action %s", key);
}
if (error) {
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 4d10a54..1375af7 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4428,6 +4428,8 @@ freeze_unroll_actions(const struct ofpact *a, const
struct ofpact *end,
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
/* These may not generate PACKET INs. */
break;
@@ -4682,6 +4684,8 @@ recirc_for_mpls(const struct ofpact *a, struct xlate_ctx
*ctx)
case OFPACT_WRITE_ACTIONS:
case OFPACT_WRITE_METADATA:
case OFPACT_GOTO_TABLE:
+ case OFPACT_REDUCE_RWND:
+ case OFPACT_SET_RWND:
default:
break;
}
@@ -4857,6 +4861,19 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t
ofpacts_len,
}
break;
+ case OFPACT_REDUCE_RWND:
+ if (is_ip_any(flow)) {
+ wc->masks.rate = 0xff;
+ flow->rate = htons(ofpact_get_REDUCE_RWND(a)->rate);
+ }
+ break;
+ case OFPACT_SET_RWND:
+ if (is_ip_any(flow)) {
+ wc->masks.rwnd = 0xffff;
+ flow->rwnd = htons(ofpact_get_SET_RWND(a)->rwnd);
+ }
+ break;
+
case OFPACT_RESUBMIT:
/* Freezing complicates resubmit. Some action in the flow
* entry found by resubmit might trigger freezing. If that
_______________________________________________
discuss mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss