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:
committed by
Simon Horman
parent
7874bdff0d
commit
c1c5c72340
@@ -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
|
||||
|
||||
@@ -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
114
lib/tc.c
Normal 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
33
lib/tc.h
Normal 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 */
|
||||
Reference in New Issue
Block a user