A similar patch has been discussed previously:
http://openvswitch.org/pipermail/dev/2010-October/004153.html
Have you looked at it?

Regards,
--
Romain Lenglet

----- Original Message -----
> From: "Rich Lane" <rich.l...@bigswitch.com>
> To: dev@openvswitch.org
> Cc: "Rich Lane" <rich.l...@bigswitch.com>
> Sent: Monday, December 10, 2012 5:16:39 PM
> Subject: [ovs-dev] [PATCH] support NXAST_SET_TUNNEL_DST action
> 
> This action allows the controller to change the destination IP of the
> encapsulating packet. It just exposes the existing Linux datapath
> functionality.
> 
> Tested by installing a flow with the new action and an output action
> to a GRE
> tunnel port. The resulting packet had the correct destination IP.
> 
> Signed-off-by: Rich Lane <rich.l...@bigswitch.com>
> ---
> I would have liked to put this in under the BSN vendor ID but there
> isn't any
> existing support for actions from other vendors. Let me know if you'd
> like me
> to add that.
> 
> I wasn't sure how to populate the tun_flags, ipv4_tos, and ipv4_ttl
> fields of
> the struct ovs_key_ipv4_tunnel. Would you rather the new OpenFlow
> action set
> all of them at once instead of just the destination IP?
> 
>  include/openflow/nicira-ext.h |   14 ++++++++++++++
>  lib/odp-util.c                |   29 +++++++++++++++++++++++++++++
>  lib/ofp-actions.c             |   25 +++++++++++++++++++++++++
>  lib/ofp-actions.h             |    9 +++++++++
>  lib/ofp-parse.c               |    5 +++++
>  lib/ofp-util.def              |    1 +
>  ofproto/ofproto-dpif.c        |    4 ++++
>  tests/ofp-actions.at          |    3 +++
>  tests/ofproto-dpif.at         |   19 +++++++++++++++++++
>  tests/ovs-ofctl.at            |    2 ++
>  10 files changed, 111 insertions(+)
> 
> diff --git a/include/openflow/nicira-ext.h
> b/include/openflow/nicira-ext.h
> index 91c96b3..a82df9c 100644
> --- a/include/openflow/nicira-ext.h
> +++ b/include/openflow/nicira-ext.h
> @@ -304,6 +304,7 @@ enum nx_action_subtype {
>      NXAST_CONTROLLER,           /* struct nx_action_controller */
>      NXAST_DEC_TTL_CNT_IDS,      /* struct nx_action_cnt_ids */
>      NXAST_WRITE_METADATA,       /* struct nx_action_write_metadata
>      */
> +    NXAST_SET_TUNNEL_DST,       /* struct nx_action_set_tunnel_dst
> */
>  };
>  
>  /* Header for Nicira-defined actions. */
> @@ -2212,4 +2213,17 @@ struct nx_action_write_metadata {
>  };
>  OFP_ASSERT(sizeof(struct nx_action_write_metadata) == 32);
>  
> +/* Action structure for NXAST_SET_TUNNEL_DST.
> + *
> + * Sets the encapsulating tunnel destination IP. */
> +struct nx_action_set_tunnel_dst {
> +    ovs_be16 type;                  /* OFPAT_VENDOR. */
> +    ovs_be16 len;                   /* Length is 16. */
> +    ovs_be32 vendor;                /* NX_VENDOR_ID. */
> +    ovs_be16 subtype;               /* NXAST_SET_TUNNEL_DST. */
> +    uint8_t pad[2];
> +    ovs_be32 tun_dst;               /* Destination IP. */
> +};
> +OFP_ASSERT(sizeof(struct nx_action_set_tunnel_dst) == 16);
> +
>  #endif /* openflow/nicira-ext.h */
> diff --git a/lib/odp-util.c b/lib/odp-util.c
> index de97fd2..8a2f76e 100644
> --- a/lib/odp-util.c
> +++ b/lib/odp-util.c
> @@ -2138,6 +2138,34 @@ commit_set_skb_mark_action(const struct flow
> *flow, struct flow *base,
>      commit_set_action(odp_actions, OVS_KEY_ATTR_SKB_MARK,
>                        &base->skb_mark, sizeof(base->skb_mark));
>  }
> +
> +static void
> +commit_set_ipv4_tunnel_action(const struct flow *flow, struct flow
> *base,
> +                              struct ofpbuf *odp_actions)
> +{
> +    struct ovs_key_ipv4_tunnel tmp;
> +
> +    /* Don't use the full ipv4_tunnel action if just tun_id changed.
> */
> +    if (base->tunnel.ip_src == flow->tunnel.ip_src &&
> +        base->tunnel.ip_dst == flow->tunnel.ip_dst) {
> +        return;
> +    }
> +
> +    base->tunnel.tun_id = flow->tunnel.tun_id;
> +    base->tunnel.ip_dst = flow->tunnel.ip_dst;
> +    base->tunnel.ip_dst = flow->tunnel.ip_dst;
> +
> +    tmp.tun_id = base->tunnel.tun_id;
> +    tmp.tun_flags = OVS_TNL_F_KEY | OVS_TNL_F_DONT_FRAGMENT;
> +    tmp.ipv4_src = base->tunnel.ip_src;
> +    tmp.ipv4_dst = base->tunnel.ip_dst;
> +    tmp.ipv4_tos = 0;
> +    tmp.ipv4_ttl = 64;
> +
> +    commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4_TUNNEL,
> +                      &tmp, sizeof(tmp));
> +}
> +
>  /* If any of the flow key data that ODP actions can modify are
>  different in
>   * 'base' and 'flow', appends ODP actions to 'odp_actions' that
>   change the flow
>   * key from 'base' into 'flow', and then changes 'base' the same
>   way. */
> @@ -2145,6 +2173,7 @@ void
>  commit_odp_actions(const struct flow *flow, struct flow *base,
>                     struct ofpbuf *odp_actions)
>  {
> +    commit_set_ipv4_tunnel_action(flow, base, odp_actions);
>      commit_set_tun_id_action(flow, base, odp_actions);
>      commit_set_ether_addr_action(flow, base, odp_actions);
>      commit_vlan_action(flow, base, odp_actions);
> diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> index b758c7c..256a982 100644
> --- a/lib/ofp-actions.c
> +++ b/lib/ofp-actions.c
> @@ -294,6 +294,7 @@ ofpact_from_nxast(const union ofp_action *a, enum
> ofputil_action_code code,
>      const struct nx_action_note *nan;
>      const struct nx_action_set_tunnel64 *nast64;
>      const struct nx_action_write_metadata *nawm;
> +    const struct nx_action_set_tunnel_dst *nastd;
>      struct ofpact_tunnel *tunnel;
>      enum ofperr error = 0;
>  
> @@ -401,6 +402,11 @@ ofpact_from_nxast(const union ofp_action *a,
> enum ofputil_action_code code,
>      case OFPUTIL_NXAST_CONTROLLER:
>          controller_from_openflow((const struct nx_action_controller
>          *) a, out);
>          break;
> +
> +    case OFPUTIL_NXAST_SET_TUNNEL_DST:
> +        nastd = (const struct nx_action_set_tunnel_dst *) a;
> +        ofpact_put_SET_TUNNEL_DST(out)->tun_dst = nastd->tun_dst;
> +        break;
>      }
>  
>      return error;
> @@ -1103,6 +1109,7 @@ ofpact_check__(const struct ofpact *a, const
> struct flow *flow, int max_ports)
>      case OFPACT_POP_QUEUE:
>      case OFPACT_FIN_TIMEOUT:
>      case OFPACT_RESUBMIT:
> +    case OFPACT_SET_TUNNEL_DST:
>          return 0;
>  
>      case OFPACT_LEARN:
> @@ -1297,6 +1304,13 @@ ofpact_fin_timeout_to_nxast(const struct
> ofpact_fin_timeout *fin_timeout,
>  }
>  
>  static void
> +ofpact_set_tunnel_dst_to_nxast(const struct ofpact_tunnel_dst
> *tunnel_dst,
> +                               struct ofpbuf *out)
> +{
> +    ofputil_put_NXAST_SET_TUNNEL_DST(out)->tun_dst =
> tunnel_dst->tun_dst;
> +}
> +
> +static void
>  ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
>  {
>      switch (a->type) {
> @@ -1369,6 +1383,10 @@ ofpact_to_nxast(const struct ofpact *a, struct
> ofpbuf *out)
>          ofputil_put_NXAST_EXIT(out);
>          break;
>  
> +    case OFPACT_SET_TUNNEL_DST:
> +        ofpact_set_tunnel_dst_to_nxast(ofpact_get_SET_TUNNEL_DST(a),
> out);
> +        break;
> +
>      case OFPACT_OUTPUT:
>      case OFPACT_ENQUEUE:
>      case OFPACT_SET_VLAN_VID:
> @@ -1496,6 +1514,7 @@ ofpact_to_openflow10(const struct ofpact *a,
> struct ofpbuf *out)
>      case OFPACT_AUTOPATH:
>      case OFPACT_NOTE:
>      case OFPACT_EXIT:
> +    case OFPACT_SET_TUNNEL_DST:
>          ofpact_to_nxast(a, out);
>          break;
>      }
> @@ -1638,6 +1657,7 @@ ofpact_to_openflow11(const struct ofpact *a,
> struct ofpbuf *out)
>      case OFPACT_AUTOPATH:
>      case OFPACT_NOTE:
>      case OFPACT_EXIT:
> +    case OFPACT_SET_TUNNEL_DST:
>          ofpact_to_nxast(a, out);
>          break;
>      }
> @@ -1763,6 +1783,7 @@ ofpact_outputs_to_port(const struct ofpact
> *ofpact, uint16_t port)
>      case OFPACT_EXIT:
>      case OFPACT_CLEAR_ACTIONS:
>      case OFPACT_GOTO_TABLE:
> +    case OFPACT_SET_TUNNEL_DST:
>      default:
>          return false;
>      }
> @@ -2059,6 +2080,10 @@ ofpact_format(const struct ofpact *a, struct
> ds *s)
>                            OVSINST_OFPIT11_GOTO_TABLE),
>                        ofpact_get_GOTO_TABLE(a)->table_id);
>          break;
> +
> +    case OFPACT_SET_TUNNEL_DST:
> +        ds_put_format(s, "set_tunnel_dst:"IP_FMT,
> IP_ARGS(&ofpact_get_SET_TUNNEL_DST(a)->tun_dst));
> +        break;
>      }
>  }
>  
> diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
> index b6cf4ba..4ddced4 100644
> --- a/lib/ofp-actions.h
> +++ b/lib/ofp-actions.h
> @@ -74,6 +74,7 @@
>                                                                      \
>      /* Metadata. */
>                                                      \
>      DEFINE_OFPACT(SET_TUNNEL,      ofpact_tunnel,        ofpact)
>         \
> +    DEFINE_OFPACT(SET_TUNNEL_DST,  ofpact_tunnel_dst,    ofpact)
>    \
>      DEFINE_OFPACT(SET_QUEUE,       ofpact_queue,         ofpact)
>         \
>      DEFINE_OFPACT(POP_QUEUE,       ofpact_null,          ofpact)
>         \
>      DEFINE_OFPACT(FIN_TIMEOUT,     ofpact_fin_timeout,   ofpact)
>         \
> @@ -318,6 +319,14 @@ struct ofpact_tunnel {
>      uint64_t tun_id;
>  };
>  
> +/* OFPACT_SET_TUNNEL_DST.
> + *
> + * Used for NXAST_SET_TUNNEL_DST. */
> +struct ofpact_tunnel_dst {
> +    struct ofpact ofpact;
> +    ovs_be32 tun_dst;
> +};
> +
>  /* OFPACT_SET_QUEUE.
>   *
>   * Used for NXAST_SET_QUEUE. */
> diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
> index 65f023a..2338e6a 100644
> --- a/lib/ofp-parse.c
> +++ b/lib/ofp-parse.c
> @@ -562,6 +562,11 @@ parse_named_action(enum ofputil_action_code
> code, const struct flow *flow,
>      case OFPUTIL_NXAST_CONTROLLER:
>          parse_controller(ofpacts, arg);
>          break;
> +
> +    case OFPUTIL_NXAST_SET_TUNNEL_DST:
> +        str_to_ip(arg, &ip);
> +        ofpact_put_SET_TUNNEL_DST(ofpacts)->tun_dst = ip;
> +        break;
>      }
>  }
>  
> diff --git a/lib/ofp-util.def b/lib/ofp-util.def
> index 6d08d8a..d22672b 100644
> --- a/lib/ofp-util.def
> +++ b/lib/ofp-util.def
> @@ -62,6 +62,7 @@ NXAST_ACTION(NXAST_CONTROLLER,
>      nx_action_controller,   0, "controller")
>  NXAST_ACTION(NXAST_DEC_TTL_CNT_IDS, nx_action_cnt_ids,      1, NULL)
>  NXAST_ACTION(NXAST_WRITE_METADATA,  nx_action_write_metadata, 0,
>               "write_metadata")
> +NXAST_ACTION(NXAST_SET_TUNNEL_DST,  nx_action_set_tunnel_dst, 0,
> "set_tunnel_dst")
>  
>  #undef OFPAT10_ACTION
>  #undef OFPAT11_ACTION
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index ca0a065..968274b 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -6051,6 +6051,10 @@ do_xlate_actions(const struct ofpact *ofpacts,
> size_t ofpacts_len,
>              xlate_table_action(ctx, ctx->flow.in_port,
>              ogt->table_id, true);
>              break;
>          }
> +
> +        case OFPACT_SET_TUNNEL_DST:
> +            ctx->flow.tunnel.ip_dst =
> ofpact_get_SET_TUNNEL_DST(a)->tun_dst;
> +            break;
>          }
>      }
>  
> diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
> index 30fcf51..7146b70 100644
> --- a/tests/ofp-actions.at
> +++ b/tests/ofp-actions.at
> @@ -118,6 +118,9 @@ ffff 0010 00002320 0014 04d2 162e 02 00
>  # actions=dec_ttl(32768,12345,90,765,1024)
>  ffff 0020 00002320 0015 000500000000 80003039005A02fd
>  0400000000000000
>  
> +# actions=set_tunnel_dst:192.168.1.1
> +ffff 0010 00002320 0017 0000 C0A80101
> +
>  ])
>  sed '/^[[#&]]/d' < test-data > input.txt
>  sed -n 's/^# //p; /^$/p' < test-data > expout
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index 6a4dc23..f2a7728 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -231,6 +231,25 @@ AT_CHECK([tail -1 stdout], [0],
>  OVS_VSWITCHD_STOP
>  AT_CLEANUP
>  
> +AT_SETUP([ofproto-dpif - set_tunnel_dst])
> +OVS_VSWITCHD_START
> +ADD_OF_PORTS([br0], [1], [2], [3], [4], [5], [90])
> +AT_DATA([flows.txt], [dnl
> +in_port=90
> actions=resubmit:1,resubmit:2,resubmit:3,resubmit:4,resubmit:5
> +in_port=1 actions=set_tunnel_dst:192.168.1.1,output:1
> +in_port=2 actions=set_tunnel_dst:192.168.1.1,output:2
> +in_port=3
> actions=set_tunnel_dst:192.168.1.2,set_tunnel_dst:192.168.1.3,output:3
> +in_port=4
> actions=set_tunnel_dst:192.168.1.4,set_tunnel_dst:192.168.1.3,output:4
> +in_port=5 actions=set_tunnel_dst:192.168.1.5
> +])
> +AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
> +AT_CHECK([ovs-appctl ofproto/trace br0
> 'tun_id(0x1),in_port(90),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'],
> [0], [stdout])
> +AT_CHECK([tail -1 stdout], [0],
> +  [Datapath actions:
> set(ipv4_tunnel(tun_id=0x1,src=0.0.0.0,dst=192.168.1.1,tos=0x0,ttl=64,flags(df,key))),1,2,set(ipv4_tunnel(tun_id=0x1,src=0.0.0.0,dst=192.168.1.3,tos=0x0,ttl=64,flags(df,key))),3,4
> +])
> +OVS_VSWITCHD_STOP
> +AT_CLEANUP
> +
>  AT_SETUP([ofproto-dpif - controller])
>  OVS_VSWITCHD_START([dnl
>     add-port br0 p1 -- set Interface p1 type=dummy
> diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
> index 7b8f38f..bd1a143 100644
> --- a/tests/ovs-ofctl.at
> +++ b/tests/ovs-ofctl.at
> @@ -86,6 +86,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
>  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_dst:192.168.1.1
>  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
>  tun_id=0x1234000056780000/0xffff0000ffff0000,actions=drop
> @@ -120,6 +121,7 @@ NXT_FLOW_MOD: ADD table:255 priority=60000
> cookie:0x123456789abcdef hard:10 acti
>  NXT_FLOW_MOD: ADD table:255
>  
> 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 table:255 tcp,tun_id=0x1234,tp_src=0x1230/0xfff0
>  cookie:0x5678 actions=FLOOD
>  NXT_FLOW_MOD: ADD table:255
>  actions=set_tunnel:0x1234,set_tunnel64:0x9876,set_tunnel64:0x123456789
> +NXT_FLOW_MOD: ADD table:255 actions=set_tunnel_dst:192.168.1.1
>  NXT_FLOW_MOD: ADD table:255
>  
> 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 table:1 actions=drop
>  NXT_FLOW_MOD: ADD table:255
>  tun_id=0x1234000056780000/0xffff0000ffff0000 actions=drop
> --
> 1.7.9.5
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
> 
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to