diff options
author | Richard Alpe <richard.alpe@ericsson.com> | 2014-11-20 04:29:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-21 15:01:29 -0500 |
commit | 0655f6a8635b1b66f2434d5556b1044c14b1ccaf (patch) | |
tree | 6c5080bcfb237f7718dee9dbc91a49b564556d43 /net/tipc/netlink.c | |
parent | 7cc76f51508219a74dca835745e4f84393820017 (diff) |
tipc: add bearer disable/enable to new netlink api
A new netlink API for tipc that can disable or enable a tipc bearer.
The new API is separated from the old API because of a bug in the
user space client (tipc-config). The problem is that older versions
of tipc-config has a very low receive limit and adding commands to
the legacy genl_opts struct causes the ctrl_getfamily() response
message to grow, subsequently breaking the tool.
The new API utilizes netlink policies for input validation. Where the
top-level netlink attributes are tipc-logical entities, like bearer.
The top level entities then contain nested attributes. In this case
a name, nested link properties and a domain.
Netlink commands implemented in this patch:
TIPC_NL_BEARER_ENABLE
TIPC_NL_BEARER_DISABLE
Netlink logical layout of bearer enable message:
-> bearer
-> name
[ -> domain ]
[
-> properties
-> priority
]
Netlink logical layout of bearer disable message:
-> bearer
-> name
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/netlink.c')
-rw-r--r-- | net/tipc/netlink.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index ad844d365340..af506ae0a129 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/netlink.c: TIPC configuration handling | 2 | * net/tipc/netlink.c: TIPC configuration handling |
3 | * | 3 | * |
4 | * Copyright (c) 2005-2006, Ericsson AB | 4 | * Copyright (c) 2005-2006, 2014, Ericsson AB |
5 | * Copyright (c) 2005-2007, Wind River Systems | 5 | * Copyright (c) 2005-2007, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "config.h" | 38 | #include "config.h" |
39 | #include "bearer.h" | ||
39 | #include <net/genetlink.h> | 40 | #include <net/genetlink.h> |
40 | 41 | ||
41 | static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | 42 | static int handle_cmd(struct sk_buff *skb, struct genl_info *info) |
@@ -68,6 +69,12 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
68 | return 0; | 69 | return 0; |
69 | } | 70 | } |
70 | 71 | ||
72 | static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = { | ||
73 | [TIPC_NLA_UNSPEC] = { .type = NLA_UNSPEC, }, | ||
74 | [TIPC_NLA_BEARER] = { .type = NLA_NESTED, }, | ||
75 | }; | ||
76 | |||
77 | /* Legacy ASCII API */ | ||
71 | static struct genl_family tipc_genl_family = { | 78 | static struct genl_family tipc_genl_family = { |
72 | .id = GENL_ID_GENERATE, | 79 | .id = GENL_ID_GENERATE, |
73 | .name = TIPC_GENL_NAME, | 80 | .name = TIPC_GENL_NAME, |
@@ -76,6 +83,7 @@ static struct genl_family tipc_genl_family = { | |||
76 | .maxattr = 0, | 83 | .maxattr = 0, |
77 | }; | 84 | }; |
78 | 85 | ||
86 | /* Legacy ASCII API */ | ||
79 | static struct genl_ops tipc_genl_ops[] = { | 87 | static struct genl_ops tipc_genl_ops[] = { |
80 | { | 88 | { |
81 | .cmd = TIPC_GENL_CMD, | 89 | .cmd = TIPC_GENL_CMD, |
@@ -83,12 +91,43 @@ static struct genl_ops tipc_genl_ops[] = { | |||
83 | }, | 91 | }, |
84 | }; | 92 | }; |
85 | 93 | ||
94 | /* Users of the legacy API (tipc-config) can't handle that we add operations, | ||
95 | * so we have a separate genl handling for the new API. | ||
96 | */ | ||
97 | struct genl_family tipc_genl_v2_family = { | ||
98 | .id = GENL_ID_GENERATE, | ||
99 | .name = TIPC_GENL_V2_NAME, | ||
100 | .version = TIPC_GENL_V2_VERSION, | ||
101 | .hdrsize = 0, | ||
102 | .maxattr = TIPC_NLA_MAX, | ||
103 | }; | ||
104 | |||
105 | static const struct genl_ops tipc_genl_v2_ops[] = { | ||
106 | { | ||
107 | .cmd = TIPC_NL_BEARER_DISABLE, | ||
108 | .doit = tipc_nl_bearer_disable, | ||
109 | .policy = tipc_nl_policy, | ||
110 | }, | ||
111 | { | ||
112 | .cmd = TIPC_NL_BEARER_ENABLE, | ||
113 | .doit = tipc_nl_bearer_enable, | ||
114 | .policy = tipc_nl_policy, | ||
115 | } | ||
116 | }; | ||
117 | |||
86 | int tipc_netlink_start(void) | 118 | int tipc_netlink_start(void) |
87 | { | 119 | { |
88 | int res; | 120 | int res; |
89 | 121 | ||
90 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); | 122 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); |
91 | if (res) { | 123 | if (res) { |
124 | pr_err("Failed to register legacy interface\n"); | ||
125 | return res; | ||
126 | } | ||
127 | |||
128 | res = genl_register_family_with_ops(&tipc_genl_v2_family, | ||
129 | tipc_genl_v2_ops); | ||
130 | if (res) { | ||
92 | pr_err("Failed to register netlink interface\n"); | 131 | pr_err("Failed to register netlink interface\n"); |
93 | return res; | 132 | return res; |
94 | } | 133 | } |
@@ -98,4 +137,5 @@ int tipc_netlink_start(void) | |||
98 | void tipc_netlink_stop(void) | 137 | void tipc_netlink_stop(void) |
99 | { | 138 | { |
100 | genl_unregister_family(&tipc_genl_family); | 139 | genl_unregister_family(&tipc_genl_family); |
140 | genl_unregister_family(&tipc_genl_v2_family); | ||
101 | } | 141 | } |