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

Ethan Jackson ethan at nicira.com
Fri Apr 1 21:19:53 UTC 2011


Looks Good to me.

Slightly curious, how did you decide to implement this patch.  Do we
support bonding over vports?  We certainly will have to in the future,
but I've never tried it with existing code base.  Did you create
several tunnels and bond them or something?

Ethan

On Fri, Apr 1, 2011 at 10:19 AM, Ben Pfaff <blp at nicira.com> 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