Fixed according to comments from Ansis. --8<--------------------------cut here-------------------------->8--
genl_lock is not exported from older kernel. Following patch add genl_exec() which can run any function (passed as arg) with genl_mutex held. Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- datapath/datapath.c | 9 ++- datapath/linux/compat/genetlink.inc | 104 +++++++++++++++++++++++++ datapath/linux/compat/include/net/genetlink.h | 6 ++ 3 files changed, 118 insertions(+), 1 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index c86c20b..025d932 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -2049,10 +2049,14 @@ static int __init dp_init(void) pr_info("Open vSwitch switching datapath %s, built "__DATE__" "__TIME__"\n", VERSION BUILDNR); - err = ovs_tnl_init(); + err = genl_exec_init(); if (err) goto error; + err = ovs_tnl_init(); + if (err) + goto error_genl_exec; + err = ovs_flow_init(); if (err) goto error_tnl_exit; @@ -2079,6 +2083,8 @@ error_flow_exit: ovs_flow_exit(); error_tnl_exit: ovs_tnl_exit(); +error_genl_exec: + genl_exec_exit(); error: return err; } @@ -2091,6 +2097,7 @@ static void dp_cleanup(void) ovs_vport_exit(); ovs_flow_exit(); ovs_tnl_exit(); + genl_exec_exit(); } module_init(dp_init); diff --git a/datapath/linux/compat/genetlink.inc b/datapath/linux/compat/genetlink.inc index bf96980..43c3227 100644 --- a/datapath/linux/compat/genetlink.inc +++ b/datapath/linux/compat/genetlink.inc @@ -146,3 +146,107 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) { } #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) + +static DEFINE_MUTEX(genl_exec_lock); + +static genl_exec_func_t genl_exec_function; +static int genl_exec_function_ret; +static void *genl_exec_data; +static struct completion done; + + +static int genl_exec_cmd(struct sk_buff *dummy, struct genl_info *dummy2) +{ + if (genl_exec_function) + genl_exec_function_ret = genl_exec_function(genl_exec_data); + complete(&done); + return 0; +} + +enum genl_exec_attr { + GENL_EXEC_UNSPEC, + GENL_EXEC_RUN, + GENL_EXEC_MAX, +}; + +static struct genl_family genl_exec_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = "GENL EXEC FAMILY", + .version = 1, + .maxattr = GENL_EXEC_MAX, +}; + +static struct genl_ops genl_exec_ops[] = { + { + .cmd = GENL_EXEC_RUN, + .doit = genl_exec_cmd, + .flags = CAP_NET_ADMIN, + }, +}; + +int genl_exec_init(void) +{ + int err; + + err = genl_register_family_with_ops(&genl_exec_family, + genl_exec_ops, + ARRAY_SIZE(genl_exec_ops)); + return err; +} + +void genl_exec_exit(void) +{ + genl_unregister_family(&genl_exec_family); +} + +/* genl_lock() is not exported from older kernel. + * Following function allows any function to be executed with + * genl_mutex held. */ + +int genl_exec(genl_exec_func_t func, void *data) +{ + struct sk_buff *skb; + int ret; + + skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + genlmsg_put(skb, 0, 0, &genl_exec_family, NLM_F_REQUEST, GENL_EXEC_RUN); + + mutex_lock(&genl_exec_lock); + genl_exec_function = func; + genl_exec_data = data; + init_completion(&done); + genlmsg_unicast(&init_net, skb, 0); + wait_for_completion(&done); + genl_exec_function = NULL; + ret = genl_exec_function_ret; + mutex_unlock(&genl_exec_lock); + + return ret; +} + +#else + +int genl_exec(genl_exec_func_t func, void *data) +{ + int ret; + + genl_lock(); + ret = func(data); + genl_unlock(); + return ret; +} +int genl_exec_init(void) +{ + return 0; +} +void genl_exec_exit(void) +{ +} + +#endif diff --git a/datapath/linux/compat/include/net/genetlink.h b/datapath/linux/compat/include/net/genetlink.h index a1ff7c1..1bbb559 100644 --- a/datapath/linux/compat/include/net/genetlink.h +++ b/datapath/linux/compat/include/net/genetlink.h @@ -170,4 +170,10 @@ static inline struct net *genl_info_net(struct genl_info *info) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) #define genlmsg_unicast(ignore_net, skb, pid) genlmsg_unicast(skb, pid) #endif + +typedef int (*genl_exec_func_t)(void *data); +int genl_exec(genl_exec_func_t func, void *data); +int genl_exec_init(void); +void genl_exec_exit(void); + #endif /* genetlink.h */ -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev