On 22 March 2017 at 04:10, Roi Dayan <[email protected]> wrote:
> From: Paul Blakey <[email protected]>
>
> Add tc flower interface that will be used to offload flows via tc
> flower classifier. Depending on the flag used (skip_sw/hw) flower
> will pass those to HW or handle them itself.
> Move some tc related functions from netdev-linux.c to tc.c
>
> Co-authored-by: Shahar Klein <[email protected]>
> Signed-off-by: Shahar Klein <[email protected]>
> Signed-off-by: Paul Blakey <[email protected]>
> Reviewed-by: Roi Dayan <[email protected]>
> ---
>  lib/automake.mk    |    2 +
>  lib/netdev-linux.c |  164 ++------
>  lib/tc.c           | 1108 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/tc.h           |  127 ++++++
>  4 files changed, 1277 insertions(+), 124 deletions(-)
>  create mode 100644 lib/tc.c
>  create mode 100644 lib/tc.h
>
> diff --git a/lib/automake.mk b/lib/automake.mk
> index abc9d0d..a6141ea 100644
> --- a/lib/automake.mk
> +++ b/lib/automake.mk
> @@ -351,6 +351,8 @@ if LINUX
>  lib_libopenvswitch_la_SOURCES += \
>         lib/dpif-netlink.c \
>         lib/dpif-netlink.h \
> +       lib/tc.h \
> +       lib/tc.c \
>         lib/if-notifier.c \
>         lib/if-notifier.h \
>         lib/netdev-linux.c \
> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
> index 9ff1333..085f530 100644
> --- a/lib/netdev-linux.c
> +++ b/lib/netdev-linux.c
> @@ -29,8 +29,6 @@
>  #include <linux/types.h>
>  #include <linux/ethtool.h>
>  #include <linux/mii.h>
> -#include <linux/pkt_cls.h>
> -#include <linux/pkt_sched.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/sockios.h>
>  #include <sys/types.h>
> @@ -74,6 +72,7 @@
>  #include "unaligned.h"
>  #include "openvswitch/vlog.h"
>  #include "util.h"
> +#include "tc.h"
>
>  VLOG_DEFINE_THIS_MODULE(netdev_linux);
>
> @@ -434,18 +433,14 @@ static const struct tc_ops *const tcs[] = {
>      NULL
>  };
>
> -static unsigned int tc_make_handle(unsigned int major, unsigned int minor);
> -static unsigned int tc_get_major(unsigned int handle);
> -static unsigned int tc_get_minor(unsigned int handle);
> -
>  static unsigned int tc_ticks_to_bytes(unsigned int rate, unsigned int ticks);
>  static unsigned int tc_bytes_to_ticks(unsigned int rate, unsigned int size);
>  static unsigned int tc_buffer_per_jiffy(unsigned int rate);
> +static struct tcmsg *netdev_linux_tc_make_request(const struct netdev *,
> +                                                  int type,
> +                                                  unsigned int flags,
> +                                                  struct ofpbuf *);
>
> -static struct tcmsg *tc_make_request(const struct netdev *, int type,
> -                                     unsigned int flags, struct ofpbuf *);
> -static int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp);
> -static int tc_add_del_ingress_qdisc(struct netdev *netdev, bool add);
>  static int tc_add_policer(struct netdev *,
>                            uint32_t kbits_rate, uint32_t kbits_burst);
>
> @@ -2055,12 +2050,18 @@ netdev_linux_set_policing(struct netdev *netdev_,
>      struct netdev_linux *netdev = netdev_linux_cast(netdev_);
>      const char *netdev_name = netdev_get_name(netdev_);
>      int error;
> +    int ifindex;
>
>      kbits_burst = (!kbits_rate ? 0       /* Force to 0 if no rate specified. 
> */
>                     : !kbits_burst ? 8000 /* Default to 8000 kbits if 0. */
>                     : kbits_burst);       /* Stick with user-specified value. 
> */
>
>      ovs_mutex_lock(&netdev->mutex);
> +    error = get_ifindex(netdev_, &ifindex);
> +    if (error) {
> +        goto out;
> +    }
> +
>      if (netdev->cache_valid & VALID_POLICING) {
>          error = netdev->netdev_policing_error;
>          if (error || (netdev->kbits_rate == kbits_rate &&
> @@ -2073,7 +2074,7 @@ netdev_linux_set_policing(struct netdev *netdev_,
>
>      COVERAGE_INC(netdev_set_policing);
>      /* Remove any existing ingress qdisc. */
> -    error = tc_add_del_ingress_qdisc(netdev_, false);
> +    error = tc_add_del_ingress_qdisc(ifindex, false);
>      if (error) {
>          VLOG_WARN_RL(&rl, "%s: removing policing failed: %s",
>                       netdev_name, ovs_strerror(error));
> @@ -2081,7 +2082,7 @@ netdev_linux_set_policing(struct netdev *netdev_,
>      }
>
>      if (kbits_rate) {
> -        error = tc_add_del_ingress_qdisc(netdev_, true);
> +        error = tc_add_del_ingress_qdisc(ifindex, true);
>          if (error) {
>              VLOG_WARN_RL(&rl, "%s: adding policing qdisc failed: %s",
>                           netdev_name, ovs_strerror(error));
> @@ -2350,7 +2351,7 @@ start_queue_dump(const struct netdev *netdev, struct 
> queue_dump_state *state)
>      struct ofpbuf request;
>      struct tcmsg *tcmsg;
>
> -    tcmsg = tc_make_request(netdev, RTM_GETTCLASS, 0, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_GETTCLASS, 0, &request);
>      if (!tcmsg) {
>          return false;
>      }
> @@ -2909,8 +2910,8 @@ codel_setup_qdisc__(struct netdev *netdev, uint32_t 
> target, uint32_t limit,
>
>      tc_del_qdisc(netdev);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWQDISC,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -3127,8 +3128,8 @@ fqcodel_setup_qdisc__(struct netdev *netdev, uint32_t 
> target, uint32_t limit,
>
>      tc_del_qdisc(netdev);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWQDISC,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -3351,8 +3352,8 @@ sfq_setup_qdisc__(struct netdev *netdev, uint32_t 
> quantum, uint32_t perturb)
>
>      tc_del_qdisc(netdev);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWQDISC,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -3538,8 +3539,8 @@ htb_setup_qdisc__(struct netdev *netdev)
>
>      tc_del_qdisc(netdev);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWQDISC,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -3592,7 +3593,8 @@ htb_setup_class__(struct netdev *netdev, unsigned int 
> handle,
>      opt.cbuffer = tc_calc_buffer(opt.ceil.rate, mtu, class->burst);
>      opt.prio = class->priority;
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWTCLASS, NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWTCLASS,
> +                                         NLM_F_CREATE, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -4201,13 +4203,11 @@ hfsc_setup_qdisc__(struct netdev * netdev)
>
>      tc_del_qdisc(netdev);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> -
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWQDISC,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> -
>      tcmsg->tcm_handle = tc_make_handle(1, 0);
>      tcmsg->tcm_parent = TC_H_ROOT;
>
> @@ -4234,12 +4234,11 @@ hfsc_setup_class__(struct netdev *netdev, unsigned 
> int handle,
>      struct ofpbuf request;
>      struct tc_service_curve min, max;
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWTCLASS, NLM_F_CREATE, &request);
> -
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWTCLASS,
> +                                         NLM_F_CREATE, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> -
>      tcmsg->tcm_handle = handle;
>      tcmsg->tcm_parent = parent;
>
> @@ -4610,102 +4609,17 @@ static double ticks_per_s;
>   */
>  static unsigned int buffer_hz;
>
> -/* Returns tc handle 'major':'minor'. */
> -static unsigned int
> -tc_make_handle(unsigned int major, unsigned int minor)
> -{
> -    return TC_H_MAKE(major << 16, minor);
> -}
> -
> -/* Returns the major number from 'handle'. */
> -static unsigned int
> -tc_get_major(unsigned int handle)
> -{
> -    return TC_H_MAJ(handle) >> 16;
> -}
> -
> -/* Returns the minor number from 'handle'. */
> -static unsigned int
> -tc_get_minor(unsigned int handle)
> -{
> -    return TC_H_MIN(handle);
> -}
> -
>  static struct tcmsg *
> -tc_make_request(const struct netdev *netdev, int type, unsigned int flags,
> -                struct ofpbuf *request)
> +netdev_linux_tc_make_request(const struct netdev *netdev, int type,
> +                             unsigned int flags, struct ofpbuf *request)
>  {
> -    struct tcmsg *tcmsg;
>      int ifindex;
> -    int error;
>
> -    error = get_ifindex(netdev, &ifindex);
> -    if (error) {
> +    if (get_ifindex(netdev, &ifindex)) {
>          return NULL;
>      }
>
> -    ofpbuf_init(request, 512);
> -    nl_msg_put_nlmsghdr(request, sizeof *tcmsg, type, NLM_F_REQUEST | flags);
> -    tcmsg = ofpbuf_put_zeros(request, sizeof *tcmsg);
> -    tcmsg->tcm_family = AF_UNSPEC;
> -    tcmsg->tcm_ifindex = ifindex;
> -    /* Caller should fill in tcmsg->tcm_handle. */
> -    /* Caller should fill in tcmsg->tcm_parent. */
> -
> -    return tcmsg;
> -}
> -
> -static int
> -tc_transact(struct ofpbuf *request, struct ofpbuf **replyp)
> -{
> -    int error = nl_transact(NETLINK_ROUTE, request, replyp);
> -    ofpbuf_uninit(request);
> -    return error;
> -}
> -
> -/* Adds or deletes a root ingress qdisc on 'netdev'.  We use this for
> - * policing configuration.
> - *
> - * This function is equivalent to running the following when 'add' is true:
> - *     /sbin/tc qdisc add dev <devname> handle ffff: ingress
> - *
> - * This function is equivalent to running the following when 'add' is false:
> - *     /sbin/tc qdisc del dev <devname> handle ffff: ingress
> - *
> - * The configuration and stats may be seen with the following command:
> - *     /sbin/tc -s qdisc show dev <devname>
> - *
> - * Returns 0 if successful, otherwise a positive errno value.
> - */
> -static int
> -tc_add_del_ingress_qdisc(struct netdev *netdev, bool add)
> -{
> -    struct ofpbuf request;
> -    struct tcmsg *tcmsg;
> -    int error;
> -    int type = add ? RTM_NEWQDISC : RTM_DELQDISC;
> -    int flags = add ? NLM_F_EXCL | NLM_F_CREATE : 0;
> -
> -    tcmsg = tc_make_request(netdev, type, flags, &request);
> -    if (!tcmsg) {
> -        return ENODEV;
> -    }
> -    tcmsg->tcm_handle = tc_make_handle(0xffff, 0);
> -    tcmsg->tcm_parent = TC_H_INGRESS;
> -    nl_msg_put_string(&request, TCA_KIND, "ingress");
> -    nl_msg_put_unspec(&request, TCA_OPTIONS, NULL, 0);
> -
> -    error = tc_transact(&request, NULL);
> -    if (error) {
> -        /* If we're deleting the qdisc, don't worry about some of the
> -         * error conditions. */
> -        if (!add && (error == ENOENT || error == EINVAL)) {
> -            return 0;
> -        }
> -        return error;
> -    }
> -
> -    return 0;
> +    return tc_make_request(ifindex, type, flags, request);
>  }
>
>  /* Adds a policer to 'netdev' with a rate of 'kbits_rate' and a burst size
> @@ -4748,8 +4662,8 @@ tc_add_policer(struct netdev *netdev,
>      tc_police.burst = tc_bytes_to_ticks(
>          tc_police.rate.rate, MIN(UINT32_MAX / 1024, kbits_burst) * 1024 / 8);
>
> -    tcmsg = tc_make_request(netdev, RTM_NEWTFILTER,
> -                            NLM_F_EXCL | NLM_F_CREATE, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWTFILTER,
> +                                         NLM_F_EXCL | NLM_F_CREATE, 
> &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -5014,7 +4928,8 @@ tc_query_class(const struct netdev *netdev,
>      struct tcmsg *tcmsg;
>      int error;
>
> -    tcmsg = tc_make_request(netdev, RTM_GETTCLASS, NLM_F_ECHO, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_GETTCLASS,
> +                                         NLM_F_ECHO, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -5040,7 +4955,7 @@ tc_delete_class(const struct netdev *netdev, unsigned 
> int handle)
>      struct tcmsg *tcmsg;
>      int error;
>
> -    tcmsg = tc_make_request(netdev, RTM_DELTCLASS, 0, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev, RTM_DELTCLASS, 0, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -5066,7 +4981,7 @@ tc_del_qdisc(struct netdev *netdev_)
>      struct tcmsg *tcmsg;
>      int error;
>
> -    tcmsg = tc_make_request(netdev_, RTM_DELQDISC, 0, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev_, RTM_DELQDISC, 0, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> @@ -5147,7 +5062,8 @@ tc_query_qdisc(const struct netdev *netdev_)
>       * in such a case we get no response at all from the kernel (!) if a
>       * builtin qdisc is in use (which is later caught by "!error &&
>       * !qdisc->size"). */
> -    tcmsg = tc_make_request(netdev_, RTM_GETQDISC, NLM_F_ECHO, &request);
> +    tcmsg = netdev_linux_tc_make_request(netdev_, RTM_GETQDISC,
> +                                         NLM_F_ECHO, &request);
>      if (!tcmsg) {
>          return ENODEV;
>      }
> diff --git a/lib/tc.c b/lib/tc.c
> new file mode 100644
> index 0000000..b1ffe75
> --- /dev/null
> +++ b/lib/tc.c
> @@ -0,0 +1,1108 @@
> +/*
> + * Copyright (c) 2016 Mellanox Technologies, Ltd.

Several of the common tc library functions were refactored out of
netdev-linux, which I would have expected to retain the Nicira
copyright. Please add the Nicira copyright here as well. If you wish
to make this more clear, I would suggest splitting this patch into the
pieces that are refactored from existing code, then adding the flower
changes in a separate patch.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to