sparse warning

  CHECK   /home/pravin/ovs/w8/datapath/linux/vport.c
/home/pravin/ovs/w8/datapath/linux/../flow.h:126:15: warning: memset
with byte count of 0
  CC [M]  /home/pravin/ovs/w8/datapath/linux/vport.o


On Fri, Jul 18, 2014 at 1:59 AM, Wenyu Zhang <wen...@vmware.com> wrote:
> Extend IPFIX exporter to export tunnel headers when both input and output
> of the port.
> Add three other_config options in IPFIX table: enable-input-sampling,
> enable-output-sampling and enable-tunnel-sampling, to control whether
> sampling tunnel info, on which direction (input or output).
> Insert sampling action before output action and the output tunnel port
> is sent to datapath in the sampling action.
> Make datapath collect output tunnel info and send it back to userpace
> in upcall message with a new additional optional attribute.
> Add a tunnel ports map to make the tunnel port lookup faster in sampling
> upcalls in IPFIX exporter. Make the IPFIX exporter generate IPFIX template
> sets with enterprise elements for the tunnel info, save the tunnel info
> in IPFIX cache entries, and send IPFIX DATA with tunnel info.
> Add flowDirection element in IPFIX templates.
>
> Signed-off-by: Wenyu Zhang <wen...@vmware.com>
> Acked-by: Romain Lenglet <rleng...@vmware.com>
> ---
>  datapath/actions.c                    |   16 +-
>  datapath/datapath.c                   |   42 +++-
>  datapath/datapath.h                   |    2 +
>  datapath/flow.h                       |   55 +++-
>  datapath/flow_netlink.c               |   58 ++++-
>  datapath/flow_netlink.h               |    2 +
>  datapath/vport-geneve.c               |   37 ++-
>  datapath/vport-gre.c                  |   35 ++-
>  datapath/vport-lisp.c                 |   39 ++-
>  datapath/vport-vxlan.c                |   38 ++-
>  datapath/vport.c                      |   33 +++
>  datapath/vport.h                      |   11 +
>  include/linux/openvswitch.h           |   21 +-
>  lib/dpif-linux.c                      |    2 +
>  lib/dpif.h                            |    1 +
>  lib/odp-util.c                        |  183 +++++++++-----
>  lib/odp-util.h                        |    2 +
>  lib/packets.h                         |    9 +-
>  ofproto/automake.mk                   |    3 +
>  ofproto/ipfix-enterprise-entities.def |   19 ++
>  ofproto/ofproto-dpif-ipfix.c          |  444 
> ++++++++++++++++++++++++++++++---
>  ofproto/ofproto-dpif-ipfix.h          |   14 +-
>  ofproto/ofproto-dpif-upcall.c         |   20 +-
>  ofproto/ofproto-dpif-xlate.c          |   51 +++-
>  ofproto/ofproto-dpif.c                |   20 ++
>  ofproto/ofproto.h                     |    3 +
>  ofproto/tunnel.c                      |    4 +
>  tests/odp.at                          |    9 +-
>  utilities/ovs-vsctl.8.in              |    8 +-
>  vswitchd/bridge.c                     |    9 +
>  vswitchd/vswitch.ovsschema            |    5 +-
>  vswitchd/vswitch.xml                  |   27 ++
>  32 files changed, 1045 insertions(+), 177 deletions(-)
>  create mode 100644 ofproto/ipfix-enterprise-entities.def
>
> diff --git a/datapath/actions.c b/datapath/actions.c
> index 39a21f4..226b849 100644
> --- a/datapath/actions.c
> +++ b/datapath/actions.c
> @@ -501,7 +501,9 @@ static int output_userspace(struct datapath *dp, struct 
> sk_buff *skb,
>  {
>         struct dp_upcall_info upcall;
>         const struct nlattr *a;
> -       int rem;
> +       int rem, err;
> +       struct ovs_tunnel_info output_tunnel_info;
> +       struct vport *vport;
>
>         BUG_ON(!OVS_CB(skb)->pkt_key);
>
> @@ -509,6 +511,7 @@ static int output_userspace(struct datapath *dp, struct 
> sk_buff *skb,
>         upcall.key = OVS_CB(skb)->pkt_key;
>         upcall.userdata = NULL;
>         upcall.portid = 0;
> +       upcall.out_tun_info = NULL;
>
>         for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
>                  a = nla_next(a, &rem)) {
> @@ -520,6 +523,17 @@ static int output_userspace(struct datapath *dp, struct 
> sk_buff *skb,
>                 case OVS_USERSPACE_ATTR_PID:
>                         upcall.portid = nla_get_u32(a);
>                         break;
> +
> +               case OVS_USERSPACE_ATTR_TUNNEL_OUT_PORT:
> +                       /* Get out tunnel info*/
> +                       vport = ovs_vport_ovsl_rcu(dp, nla_get_u32(a));
> +                       if (vport->ops->get_out_tun_info){
> +                               err = vport->ops->get_out_tun_info(vport, 
> skb, &output_tunnel_info);
> +                               if (err == 0) {
> +                                       upcall.out_tun_info = 
> &output_tunnel_info;
> +                               }
> +                        }
> +                       break;
>                 }
>         }
>
According to ovs coding style, variable are declared in local block,
so you can move vport and err to respective local block.

In case of error from get_out_tun_info() or invalid vport, we can skip
user upcall, since userspace will discard this data anyways.

....

>
>  static size_t upcall_msg_size(const struct nlattr *userdata,
> +                              bool out_tun_key,
>                               unsigned int hdrlen)
>  {
>         size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
> @@ -418,6 +429,10 @@ static size_t upcall_msg_size(const struct nlattr 
> *userdata,
>         if (userdata)
>                 size += NLA_ALIGN(userdata->nla_len);
>
> +       /* OVS_PACKET_ATTR_OUT_TUNNEL_KEY */
> +        if (out_tun_key)
> +               size += nla_total_size(tun_key_attr_size());
> +
>         return size;
>  }
>

Can you pass down upcall_info to upcall_msg_size(), it look more
consistent that way.


>  static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
> -                                        const struct iphdr *iph, __be64 
> tun_id,
> -                                        __be16 tun_flags,
> -                                        struct geneve_opt *opts,
> -                                        u8 opts_len)
> +                                         const struct iphdr *iph,
> +                                         const void *tph,
> +                                         __be64 tun_id,
> +                                         __be16 tun_flags,
> +                                         struct geneve_opt *opts,
> +                                         u8 opts_len)
>  {

Rather than passing down tph, can just pass tp_src_port and
tp_dst_port? we can avoid if conditions in this function.

>         tun_info->tunnel.tun_id = tun_id;
>         tun_info->tunnel.ipv4_src = iph->saddr;
> @@ -79,6 +83,21 @@ static inline void ovs_flow_tun_info_init(struct 
> ovs_tunnel_info *tun_info,
>         tun_info->tunnel.ipv4_ttl = iph->ttl;
>         tun_info->tunnel.tun_flags = tun_flags;
>
> +       /* For the tunnel types on the top of IPsec,the tp_src and tp_dst of
> +        * the upper tunnel are used.
> +        * E.g: GRE over IPSEC, the tp_src and tp_port are zero.
> +        */
> +       if (tph &&
> +           (iph->protocol == IPPROTO_UDP ||
> +            iph->protocol == IPPROTO_TCP)) {
> +               const struct udphdr * udp_hdr = tph;
> +               tun_info->tunnel.tp_src = udp_hdr->source;
> +               tun_info->tunnel.tp_dst = udp_hdr->dest;
> +       } else {
> +               tun_info->tunnel.tp_src = 0;
> +               tun_info->tunnel.tp_dst = 0;
> +        }
> +
>         /* clear struct padding. */
>         memset((unsigned char *) &tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, 0,
>                sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE);
> @@ -87,6 +106,30 @@ static inline void ovs_flow_tun_info_init(struct 
> ovs_tunnel_info *tun_info,
>         tun_info->options_len = opts_len;
>  }
>
> +static inline void ovs_flow_out_tun_info_init(struct ovs_tunnel_info 
> *out_tun_info,
> +                                             const struct ovs_tunnel_info 
> *tun_info,
> +                                             __be32 saddr,
> +                                             __be16 tp_src,
> +                                             __be16 tp_dst)
> +{
> +       out_tun_info->tunnel.tun_id = tun_info->tunnel.tun_id;
> +       out_tun_info->tunnel.ipv4_src = saddr;
> +       out_tun_info->tunnel.ipv4_dst = tun_info->tunnel.ipv4_dst;
> +       out_tun_info->tunnel.ipv4_tos = tun_info->tunnel.ipv4_tos;
> +       out_tun_info->tunnel.ipv4_ttl = tun_info->tunnel.ipv4_ttl;
> +       out_tun_info->tunnel.tun_flags = tun_info->tunnel.tun_flags;
> +
> +       out_tun_info->tunnel.tp_src = tp_src;
> +       out_tun_info->tunnel.tp_dst = tp_dst;
> +
> +       /* clear struct padding. */
> +       memset((unsigned char *) &tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, 0,
> +              sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE);
> +
> +       out_tun_info->options = tun_info->options;
> +       out_tun_info->options_len = tun_info->options_len;
> +}
> +

If you change ovs_flow_tun_info_init() according to comments above,
there is no need for separate function ovs_flow_out_tun_info_init().
You can use ovs_flow_tun_info_init() to setup out_tun_key.


>
> +static int geneve_get_out_tun_info(struct vport *vport, struct sk_buff *skb,
> +                                  struct ovs_tunnel_info *out_tun_info)
> +{
> +       struct geneve_port *geneve_port = geneve_vport(vport);
> +
> +       if (unlikely(!OVS_CB(skb)->tun_info))
> +               return -EINVAL;
You can move this check inside ovs_vport_get_out_tun_info().


> +
> +
> +

extra blank lines.

> +       /*
> +        * Get tp_src and tp_dst, refert to geneve_build_header().
> +        */
> +       return ovs_vport_get_out_tun_info(out_tun_info, OVS_CB(skb)->tun_info,
> +                                         ovs_dp_get_net(vport->dp),
> +                                         IPPROTO_UDP, skb->mark,
> +                                         vxlan_src_port(1, USHRT_MAX, skb),
> +                                         inet_sport(geneve_port->sock->sk));
> +
> +}
> +

.....
>  }
> +
> +int ovs_vport_get_out_tun_info(struct ovs_tunnel_info *out_tun_info,
> +                              const struct ovs_tunnel_info *tun_info,
> +                              struct net *net,
> +                              u8 ipproto,
> +                              u32 skb_mark,
> +                              __be16 tp_src,
> +                              __be16 tp_dst)
> +{
> +       struct rtable *rt;
...
> +
> +       ip_rt_put(rt);
> +
> +       /* Generate out_tun_info based on tun_info, saddr, tp_src and tp_dst*/
> +        ovs_flow_out_tun_info_init(out_tun_info, tun_info, saddr, tp_src, 
> tp_dst);
> +
Use tab for indentation.

> +       return 0;
> +}
> diff --git a/datapath/vport.h b/datapath/vport.h
....

> -       OVS_PACKET_ATTR_USERDATA,    /* OVS_ACTION_ATTR_USERSPACE arg. */
> +       OVS_PACKET_ATTR_PACKET,         /* Packet data. */
> +       OVS_PACKET_ATTR_KEY,            /* Nested OVS_KEY_ATTR_* attributes. 
> */
> +       OVS_PACKET_ATTR_ACTIONS,        /* Nested OVS_ACTION_ATTR_* 
> attributes. */
> +       OVS_PACKET_ATTR_USERDATA,       /* OVS_ACTION_ATTR_USERSPACE arg. */
> +       OVS_PACKET_ATTR_OUT_TUNNEL_KEY, /* Nested OVS_TUNNEL_KEY_ATTR_* 
> attributes */
>         __OVS_PACKET_ATTR_MAX
>  };
>

After reading patch I think "egress_tunnel_info" better than
out_tunnel_key, Can you change all names to use egress_tunnel_info
suffix?
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to