Skip to content

Commit

Permalink
net_sched: add network namespace support for tc actions
Browse files Browse the repository at this point in the history
Currently tc actions are stored in a per-module hashtable,
therefore are visible to all network namespaces. This is
probably the last part of the tc subsystem which is not
aware of netns now. This patch makes them per-netns,
several tc action API's need to be adjusted for this.

The tc action API code is ugly due to historical reasons,
we need to refactor that code in the future.

Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
congwang authored and davem330 committed Feb 25, 2016
1 parent 1d4150c commit ddf97cc
Show file tree
Hide file tree
Showing 14 changed files with 746 additions and 149 deletions.
58 changes: 47 additions & 11 deletions include/net/act_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

struct tcf_common {
struct hlist_node tcfc_head;
Expand Down Expand Up @@ -87,31 +89,65 @@ struct tc_action {
__u32 type; /* for backward compat(TCA_OLD_COMPAT) */
__u32 order;
struct list_head list;
struct tcf_hashinfo *hinfo;
};

struct tc_action_ops {
struct list_head head;
struct tcf_hashinfo *hinfo;
char kind[IFNAMSIZ];
__u32 type; /* TBD to match kind */
struct module *owner;
int (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32);
int (*lookup)(struct net *, struct tc_action *, u32);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *act, int ovr,
int bind);
int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int, struct tc_action *);
};

struct tc_action_net {
struct tcf_hashinfo *hinfo;
const struct tc_action_ops *ops;
};

int tcf_hash_search(struct tc_action *a, u32 index);
u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo);
int tcf_hash_check(u32 index, struct tc_action *a, int bind);
int tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a,
int size, int bind, bool cpustats);
static inline
int tc_action_net_init(struct tc_action_net *tn, const struct tc_action_ops *ops,
unsigned int mask)
{
int err = 0;

tn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL);
if (!tn->hinfo)
return -ENOMEM;
tn->ops = ops;
err = tcf_hashinfo_init(tn->hinfo, mask);
if (err)
kfree(tn->hinfo);
return err;
}

void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
struct tcf_hashinfo *hinfo);

static inline void tc_action_net_exit(struct tc_action_net *tn)
{
tcf_hashinfo_destroy(tn->ops, tn->hinfo);
}

int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
struct netlink_callback *cb, int type,
struct tc_action *a);
int tcf_hash_search(struct tc_action_net *tn, struct tc_action *a, u32 index);
u32 tcf_hash_new_index(struct tc_action_net *tn);
int tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action *a,
int bind);
int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
struct tc_action *a, int size, int bind, bool cpustats);
void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
void tcf_hash_insert(struct tc_action *a);
void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);

int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);

Expand All @@ -120,8 +156,8 @@ static inline int tcf_hash_release(struct tc_action *a, bool bind)
return __tcf_hash_release(a, bind, false);
}

int tcf_register_action(struct tc_action_ops *a, unsigned int mask);
int tcf_unregister_action(struct tc_action_ops *a);
int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
int tcf_unregister_action(struct tc_action_ops *a, struct pernet_operations *ops);
int tcf_action_destroy(struct list_head *actions, int bind);
int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions,
struct tcf_result *res);
Expand Down
Loading

0 comments on commit ddf97cc

Please sign in to comment.