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

Reply via email to