]> git.proxmox.com Git - ovs.git/blame - lib/tc.c
tc: Introduce tc module
[ovs.git] / lib / tc.c
CommitLineData
c1c5c723
PB
1/*
2 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
18#include "tc.h"
19#include <errno.h>
20#include "netlink-socket.h"
21#include "netlink.h"
22#include "openvswitch/ofpbuf.h"
23#include "openvswitch/vlog.h"
24
25VLOG_DEFINE_THIS_MODULE(tc);
26
27/* Returns tc handle 'major':'minor'. */
28unsigned int
29tc_make_handle(unsigned int major, unsigned int minor)
30{
31 return TC_H_MAKE(major << 16, minor);
32}
33
34/* Returns the major number from 'handle'. */
35unsigned int
36tc_get_major(unsigned int handle)
37{
38 return TC_H_MAJ(handle) >> 16;
39}
40
41/* Returns the minor number from 'handle'. */
42unsigned int
43tc_get_minor(unsigned int handle)
44{
45 return TC_H_MIN(handle);
46}
47
48struct tcmsg *
49tc_make_request(int ifindex, int type, unsigned int flags,
50 struct ofpbuf *request)
51{
52 struct tcmsg *tcmsg;
53
54 ofpbuf_init(request, 512);
55 nl_msg_put_nlmsghdr(request, sizeof *tcmsg, type, NLM_F_REQUEST | flags);
56 tcmsg = ofpbuf_put_zeros(request, sizeof *tcmsg);
57 tcmsg->tcm_family = AF_UNSPEC;
58 tcmsg->tcm_ifindex = ifindex;
59 /* Caller should fill in tcmsg->tcm_handle. */
60 /* Caller should fill in tcmsg->tcm_parent. */
61
62 return tcmsg;
63}
64
65int
66tc_transact(struct ofpbuf *request, struct ofpbuf **replyp)
67{
68 int error = nl_transact(NETLINK_ROUTE, request, replyp);
69 ofpbuf_uninit(request);
70 return error;
71}
72
73/* Adds or deletes a root ingress qdisc on device with specified ifindex.
74 *
75 * This function is equivalent to running the following when 'add' is true:
76 * /sbin/tc qdisc add dev <devname> handle ffff: ingress
77 *
78 * This function is equivalent to running the following when 'add' is false:
79 * /sbin/tc qdisc del dev <devname> handle ffff: ingress
80 *
81 * Where dev <devname> is the device with specified ifindex name.
82 *
83 * The configuration and stats may be seen with the following command:
84 * /sbin/tc -s qdisc show dev <devname>
85 *
86 * Returns 0 if successful, otherwise a positive errno value.
87 */
88int
89tc_add_del_ingress_qdisc(int ifindex, bool add)
90{
91 struct ofpbuf request;
92 struct tcmsg *tcmsg;
93 int error;
94 int type = add ? RTM_NEWQDISC : RTM_DELQDISC;
95 int flags = add ? NLM_F_EXCL | NLM_F_CREATE : 0;
96
97 tcmsg = tc_make_request(ifindex, type, flags, &request);
98 tcmsg->tcm_handle = tc_make_handle(0xffff, 0);
99 tcmsg->tcm_parent = TC_H_INGRESS;
100 nl_msg_put_string(&request, TCA_KIND, "ingress");
101 nl_msg_put_unspec(&request, TCA_OPTIONS, NULL, 0);
102
103 error = tc_transact(&request, NULL);
104 if (error) {
105 /* If we're deleting the qdisc, don't worry about some of the
106 * error conditions. */
107 if (!add && (error == ENOENT || error == EINVAL)) {
108 return 0;
109 }
110 return error;
111 }
112
113 return 0;
114}