[ovs-dev] [PATCH v2] ofp-actions: Add a new action to truncate a packet.

pravin shelar pshelar at ovn.org
Mon Apr 11 20:14:26 UTC 2016


On Fri, Apr 1, 2016 at 5:37 PM, William Tu <u9012063 at gmail.com> wrote:
> The patch proposes adding a new action to support packet truncation.  The new
> action is formatted as 'output(port=n,max_len=m)', as output to port n, with
> packet size being MIN(original_size, m).
>
> One use case is to enable port mirroring to send smaller packets to the
> destination port so that only useful packet information is mirrored/copied,
> saving some performance overhead of copying entire packet payload.  Example
> use case is below as well as shown in the testcases:
>
>     - Output to port 1 with max_len 100 bytes.
>     - The output packet size on port 1 will be MIN(original_packet_size, 100).
>     # ovs-ofctl add-flow br0 'actions=output(port=1,max_len=100)'
>
>     - The scope of max_len is limited to output action itself.  The following
>       output:1 and output:2 will be the original packet size.
>     # ovs-ofctl add-flow br0 'actions=output(port=1,max_len=100),output:1,output:2'
>
> Implementation/Limitaions:
>
>     - The patch adds a new OpenFlow extension action OFPACT_OUTPUT_TRUNC, and
>       a new datapath action, OVS_ACTION_ATTR_OUTPUT_TRUNC.
>     - The minimum value of max_len is 60 byte (minimum Ethernet frame size).
>       This is defined in OVS_ACTION_OUTPUT_MIN.
>     - Only "output(port=[0-9]*,max_len=<N>)" is supported.  Output to IN_PORT,
>       TABLE, NORMAL, FLOOD, ALL, and LOCAL are not supported.
>
> Signed-off-by: William Tu <u9012063 at gmail.com>
> ---
> v1->v2
>     - Create new OpenFlow action, do not reuse OFPACT_OUTPUT
>     - Create new datapath action
>
> ---
>  datapath/actions.c                                |  18 +++-
>  datapath/datapath.h                               |   1 +
>  datapath/flow_netlink.c                           |   9 ++
>  datapath/linux/compat/include/linux/openvswitch.h |   9 ++
>  datapath/vport.c                                  |   6 ++
>  lib/dp-packet.c                                   |   1 +
>  lib/dp-packet.h                                   |   1 +
>  lib/dpif-netdev.c                                 |  28 ++++++
>  lib/dpif.c                                        |   1 +
>  lib/netdev.c                                      |   8 ++
>  lib/odp-execute.c                                 |   2 +
>  lib/odp-util.c                                    |  11 ++-
>  lib/ofp-actions.c                                 | 102 ++++++++++++++++++++++
>  lib/ofp-actions.h                                 |  10 +++
>  ofproto/ofproto-dpif-sflow.c                      |   6 ++
>  ofproto/ofproto-dpif-xlate.c                      |  39 +++++++++
>  tests/ofproto-dpif.at                             |  53 +++++++++++
>  tests/system-traffic.at                           |  66 ++++++++++++++
>  18 files changed, 366 insertions(+), 5 deletions(-)
>
> diff --git a/datapath/actions.c b/datapath/actions.c
> index dcf8591..a1a1241 100644
> --- a/datapath/actions.c
> +++ b/datapath/actions.c
> @@ -738,10 +738,13 @@ err:
>  }
>
>  static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
> -                     struct sw_flow_key *key)
> +                     uint16_t max_len, struct sw_flow_key *key)
>  {
>         struct vport *vport = ovs_vport_rcu(dp, out_port);
>
> +       if (unlikely(max_len != 0))
> +               OVS_CB(skb)->max_len = max_len;
> +
>         if (likely(vport)) {
>                 u16 mru = OVS_CB(skb)->mru;
>
> @@ -1034,6 +1037,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
>          * is slightly obscure just to avoid that.
>          */
>         int prev_port = -1;
> +       uint16_t max_len = 0;
>         const struct nlattr *a;
>         int rem;
>
> @@ -1045,9 +1049,10 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
>                         struct sk_buff *out_skb = skb_clone(skb, GFP_ATOMIC);
>
>                         if (out_skb)
> -                               do_output(dp, out_skb, prev_port, key);
> +                               do_output(dp, out_skb, prev_port, max_len, key);
>
>                         prev_port = -1;
> +                       max_len = 0;
>                 }
>
>                 switch (nla_type(a)) {
> @@ -1055,6 +1060,13 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
>                         prev_port = nla_get_u32(a);
>                         break;
>
> +        case OVS_ACTION_ATTR_OUTPUT_TRUNC: {
> +                       struct ovs_action_output_trunc *output_trunc = nla_data(a);
> +                       prev_port = output_trunc->port;
> +                       max_len = output_trunc->max_len;
> +                       break;
> +        }
> +

The datapath truncate action should not be associated with output
action. It should be general truncate action with truncate length
parameter. This way we can apply it to actions other than output.



More information about the dev mailing list