[ovs-dev] [PATCH 2/2] netdev-vport: Implement 'send' function.

Justin Petbot jpetbot at gmail.com
Fri Apr 1 17:55:31 UTC 2011


Looks good to me.

On Fri,  1 Apr 2011, at 10:19:05 AM, Ben Pfaff wrote:
> The new implementation of the bonding code expects to be able to send
> packets on netdevs using netdev_send().  This implements it.
> ---
>  lib/dpif-linux.c   |   28 ++++++++++++++++++++++++++++
>  lib/dpif-linux.h   |    3 +++
>  lib/netdev-vport.c |   38 +++++++++++++++++++++++++++++++++++++-
>  3 files changed, 68 insertions(+), 1 deletions(-)
> 
> diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
> index bdc7703..b5590c4 100644
> --- a/lib/dpif-linux.c
> +++ b/lib/dpif-linux.c
> @@ -1027,6 +1027,34 @@ dpif_linux_is_internal_device(const char *name)
>      return reply.type == ODP_VPORT_TYPE_INTERNAL;
>  }
>  
> +int
> +dpif_linux_vport_send(int dp_ifindex, uint32_t port_no,
> +                      const void *data, size_t size)
> +{
> +    struct odp_header *execute;
> +    struct ofpbuf *buf;
> +    size_t actions_ofs;
> +    int error;
> +
> +    buf = ofpbuf_new(128 + size);
> +
> +    nl_msg_put_genlmsghdr(buf, 0, odp_packet_family, NLM_F_REQUEST,
> +                          ODP_PACKET_CMD_EXECUTE, 1);
> +
> +    execute = ofpbuf_put_uninit(buf, sizeof *execute);
> +    execute->dp_ifindex = dp_ifindex;
> +
> +    nl_msg_put_unspec(buf, ODP_PACKET_ATTR_PACKET, data, size);
> +
> +    actions_ofs = nl_msg_start_nested(buf, ODP_PACKET_ATTR_ACTIONS);
> +    nl_msg_put_u32(buf, ODP_ACTION_ATTR_OUTPUT, port_no);
> +    nl_msg_end_nested(buf, actions_ofs);
> +
> +    error = nl_sock_transact(genl_sock, buf, NULL);
> +    ofpbuf_delete(buf);
> +    return error;
> +}
> +
>  static void
>  dpif_linux_port_changed(const struct rtnetlink_link_change *change,
>                          void *dpif_)
> diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h
> index bd7b07c..f942a8c 100644
> --- a/lib/dpif-linux.h
> +++ b/lib/dpif-linux.h
> @@ -53,4 +53,7 @@ int dpif_linux_vport_get(const char *name, struct dpif_linux_vport *reply,
>  
>  bool dpif_linux_is_internal_device(const char *name);
>  
> +int dpif_linux_vport_send(int dp_ifindex, uint32_t port_no,
> +                          const void *data, size_t size);
> +
>  #endif /* dpif-linux.h */
> diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
> index 39a1bb9..be26941 100644
> --- a/lib/netdev-vport.c
> +++ b/lib/netdev-vport.c
> @@ -56,6 +56,8 @@ struct netdev_vport_notifier {
>  struct netdev_dev_vport {
>      struct netdev_dev netdev_dev;
>      struct ofpbuf *options;
> +    int dp_ifindex;             /* -1 if unknown. */
> +    uint32_t port_no;           /* UINT32_MAX if unknown. */
>  };
>  
>  struct netdev_vport {
> @@ -185,10 +187,14 @@ netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
>      const struct vport_class *vport_class = vport_class_cast(netdev_class);
>      struct ofpbuf *options = NULL;
>      struct shash fetched_args;
> +    int dp_ifindex;
> +    uint32_t port_no;
>      int error;
>  
>      shash_init(&fetched_args);
>  
> +    dp_ifindex = -1;
> +    port_no = UINT32_MAX;
>      if (!shash_is_empty(args)) {
>          /* Parse the provided configuration. */
>          options = ofpbuf_new(64);
> @@ -215,6 +221,8 @@ netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
>                              name, strerror(error));
>              } else {
>                  options = ofpbuf_clone_data(reply.options, reply.options_len);
> +                dp_ifindex = reply.dp_ifindex;
> +                port_no = reply.port_no;
>              }
>              ofpbuf_delete(buf);
>          } else {
> @@ -231,6 +239,8 @@ netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
>                          shash_is_empty(&fetched_args) ? args : &fetched_args,
>                          netdev_class);
>          dev->options = options;
> +        dev->dp_ifindex = dp_ifindex;
> +        dev->port_no = port_no;
>  
>          *netdev_devp = &dev->netdev_dev;
>          route_table_register();
> @@ -312,6 +322,32 @@ netdev_vport_set_config(struct netdev_dev *dev_, const struct shash *args)
>  }
>  
>  static int
> +netdev_vport_send(struct netdev *netdev, const void *data, size_t size)
> +{
> +    struct netdev_dev *dev_ = netdev_get_dev(netdev);
> +    struct netdev_dev_vport *dev = netdev_dev_vport_cast(dev_);
> +
> +    if (dev->dp_ifindex == -1) {
> +        const char *name = netdev_get_name(netdev);
> +        struct dpif_linux_vport reply;
> +        struct ofpbuf *buf;
> +        int error;
> +
> +        error = dpif_linux_vport_get(name, &reply, &buf);
> +        if (error) {
> +            VLOG_ERR_RL(&rl, "%s: failed to query vport for send (%s)",
> +                        name, strerror(error));
> +            return error;
> +        }
> +        dev->dp_ifindex = reply.dp_ifindex;
> +        dev->port_no = reply.port_no;
> +        ofpbuf_delete(buf);
> +    }
> +
> +    return dpif_linux_vport_send(dev->dp_ifindex, dev->port_no, data, size);
> +}
> +
> +static int
>  netdev_vport_set_etheraddr(struct netdev *netdev,
>                             const uint8_t mac[ETH_ADDR_LEN])
>  {
> @@ -936,7 +972,7 @@ unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
>      NULL,                       /* recv_wait */             \
>      NULL,                       /* drain */                 \
>                                                              \
> -    NULL,                       /* send */                  \
> +    netdev_vport_send,          /* send */                  \
>      NULL,                       /* send_wait */             \
>                                                              \
>      netdev_vport_set_etheraddr,                             \
> -- 
> 1.7.1
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev



More information about the dev mailing list