2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-25 15:07:05 +00:00

tc: Introduce tc module

Add tc module to expose tc operations to be used by other modules.
Move some tc related functions from netdev-linux.c to tc.c
This patch doesn't change any functionality.

Signed-off-by: Paul Blakey <paulb@mellanox.com>
Co-authored-by: Roi Dayan <roid@mellanox.com>
Signed-off-by: Roi Dayan <roid@mellanox.com>
Acked-by: Joe Stringer <joe@ovn.org>
Acked-by: Flavio Leitner <fbl@sysclose.org>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
This commit is contained in:
Paul Blakey
2017-06-13 18:03:24 +03:00
committed by Simon Horman
parent 7874bdff0d
commit c1c5c72340
4 changed files with 151 additions and 100 deletions

View File

@@ -368,7 +368,9 @@ lib_libopenvswitch_la_SOURCES += \
lib/rtnetlink.c \
lib/rtnetlink.h \
lib/route-table.c \
lib/route-table.h
lib/route-table.h \
lib/tc.c \
lib/tc.h
endif
if DPDK_NETDEV

View File

@@ -29,9 +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>
#include <sys/ioctl.h>
@@ -70,6 +67,7 @@
#include "openvswitch/shash.h"
#include "socket-util.h"
#include "sset.h"
#include "tc.h"
#include "timer.h"
#include "unaligned.h"
#include "openvswitch/vlog.h"
@@ -434,22 +432,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 *tc_make_request(int ifindex, int type,
unsigned int flags, struct ofpbuf *);
static struct tcmsg *netdev_linux_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(int ifindex, bool add);
static int tc_add_policer(struct netdev *,
uint32_t kbits_rate, uint32_t kbits_burst);
@@ -4657,44 +4647,6 @@ 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(int ifindex, int type, unsigned int flags,
struct ofpbuf *request)
{
struct tcmsg *tcmsg;
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 struct tcmsg *
netdev_linux_tc_make_request(const struct netdev *netdev, int type,
unsigned int flags, struct ofpbuf *request)
@@ -4710,56 +4662,6 @@ netdev_linux_tc_make_request(const struct netdev *netdev, int type,
return tc_make_request(ifindex, type, flags, request);
}
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(int ifindex, 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(ifindex, type, flags, &request);
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;
}
/* Adds a policer to 'netdev' with a rate of 'kbits_rate' and a burst size
* of 'kbits_burst'.
*

114
lib/tc.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <config.h>
#include "tc.h"
#include <errno.h>
#include "netlink-socket.h"
#include "netlink.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(tc);
/* Returns tc handle 'major':'minor'. */
unsigned int
tc_make_handle(unsigned int major, unsigned int minor)
{
return TC_H_MAKE(major << 16, minor);
}
/* Returns the major number from 'handle'. */
unsigned int
tc_get_major(unsigned int handle)
{
return TC_H_MAJ(handle) >> 16;
}
/* Returns the minor number from 'handle'. */
unsigned int
tc_get_minor(unsigned int handle)
{
return TC_H_MIN(handle);
}
struct tcmsg *
tc_make_request(int ifindex, int type, unsigned int flags,
struct ofpbuf *request)
{
struct tcmsg *tcmsg;
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;
}
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 device with specified ifindex.
*
* 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
*
* Where dev <devname> is the device with specified ifindex name.
*
* 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.
*/
int
tc_add_del_ingress_qdisc(int ifindex, 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(ifindex, type, flags, &request);
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;
}

33
lib/tc.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TC_H
#define TC_H 1
#include <linux/pkt_cls.h>
#include <linux/pkt_sched.h>
#include <linux/rtnetlink.h>
#include "openvswitch/ofpbuf.h"
unsigned int tc_make_handle(unsigned int major, unsigned int minor);
unsigned int tc_get_major(unsigned int handle);
unsigned int tc_get_minor(unsigned int handle);
struct tcmsg *tc_make_request(int ifindex, int type,
unsigned int flags, struct ofpbuf *);
int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp);
int tc_add_del_ingress_qdisc(int ifindex, bool add);
#endif /* tc.h */