diff options
author | Jiri Pirko <jpirko@redhat.com> | 2012-04-04 08:16:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-04 20:30:40 -0400 |
commit | 2615598fc100451c71b83d06bdf5faead619a40e (patch) | |
tree | d8df65665fecf7dfd25d42ba862c6f929be43ca3 | |
parent | bd856615c128c40d189d6dd68dde7afe15ed3446 (diff) |
team: add binary option type
For transfering generic binary data (e.g. BPF code), introduce new
binary option type.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/team/team.c | 30 | ||||
-rw-r--r-- | include/linux/if_team.h | 8 |
2 files changed, 34 insertions, 4 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 0db6e66ea98d..ea96f822de52 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -1145,10 +1145,7 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { | |||
1145 | }, | 1145 | }, |
1146 | [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, | 1146 | [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, |
1147 | [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, | 1147 | [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, |
1148 | [TEAM_ATTR_OPTION_DATA] = { | 1148 | [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, |
1149 | .type = NLA_BINARY, | ||
1150 | .len = TEAM_STRING_MAX_LEN, | ||
1151 | }, | ||
1152 | }; | 1149 | }; |
1153 | 1150 | ||
1154 | static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) | 1151 | static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) |
@@ -1257,6 +1254,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb, | |||
1257 | list_for_each_entry(option, &team->option_list, list) { | 1254 | list_for_each_entry(option, &team->option_list, list) { |
1258 | struct nlattr *option_item; | 1255 | struct nlattr *option_item; |
1259 | long arg; | 1256 | long arg; |
1257 | struct team_option_binary tbinary; | ||
1260 | 1258 | ||
1261 | /* Include only changed options if fill all mode is not on */ | 1259 | /* Include only changed options if fill all mode is not on */ |
1262 | if (!fillall && !option->changed) | 1260 | if (!fillall && !option->changed) |
@@ -1290,6 +1288,15 @@ static int team_nl_fill_options_get(struct sk_buff *skb, | |||
1290 | (char *) arg)) | 1288 | (char *) arg)) |
1291 | goto nla_put_failure; | 1289 | goto nla_put_failure; |
1292 | break; | 1290 | break; |
1291 | case TEAM_OPTION_TYPE_BINARY: | ||
1292 | if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY)) | ||
1293 | goto nla_put_failure; | ||
1294 | arg = (long) &tbinary; | ||
1295 | team_option_get(team, option, &arg); | ||
1296 | if (nla_put(skb, TEAM_ATTR_OPTION_DATA, | ||
1297 | tbinary.data_len, tbinary.data)) | ||
1298 | goto nla_put_failure; | ||
1299 | break; | ||
1293 | default: | 1300 | default: |
1294 | BUG(); | 1301 | BUG(); |
1295 | } | 1302 | } |
@@ -1374,6 +1381,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) | |||
1374 | case NLA_STRING: | 1381 | case NLA_STRING: |
1375 | opt_type = TEAM_OPTION_TYPE_STRING; | 1382 | opt_type = TEAM_OPTION_TYPE_STRING; |
1376 | break; | 1383 | break; |
1384 | case NLA_BINARY: | ||
1385 | opt_type = TEAM_OPTION_TYPE_BINARY; | ||
1386 | break; | ||
1377 | default: | 1387 | default: |
1378 | goto team_put; | 1388 | goto team_put; |
1379 | } | 1389 | } |
@@ -1382,19 +1392,31 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) | |||
1382 | list_for_each_entry(option, &team->option_list, list) { | 1392 | list_for_each_entry(option, &team->option_list, list) { |
1383 | long arg; | 1393 | long arg; |
1384 | struct nlattr *opt_data_attr; | 1394 | struct nlattr *opt_data_attr; |
1395 | struct team_option_binary tbinary; | ||
1396 | int data_len; | ||
1385 | 1397 | ||
1386 | if (option->type != opt_type || | 1398 | if (option->type != opt_type || |
1387 | strcmp(option->name, opt_name)) | 1399 | strcmp(option->name, opt_name)) |
1388 | continue; | 1400 | continue; |
1389 | opt_found = true; | 1401 | opt_found = true; |
1390 | opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA]; | 1402 | opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA]; |
1403 | data_len = nla_len(opt_data_attr); | ||
1391 | switch (opt_type) { | 1404 | switch (opt_type) { |
1392 | case TEAM_OPTION_TYPE_U32: | 1405 | case TEAM_OPTION_TYPE_U32: |
1393 | arg = nla_get_u32(opt_data_attr); | 1406 | arg = nla_get_u32(opt_data_attr); |
1394 | break; | 1407 | break; |
1395 | case TEAM_OPTION_TYPE_STRING: | 1408 | case TEAM_OPTION_TYPE_STRING: |
1409 | if (data_len > TEAM_STRING_MAX_LEN) { | ||
1410 | err = -EINVAL; | ||
1411 | goto team_put; | ||
1412 | } | ||
1396 | arg = (long) nla_data(opt_data_attr); | 1413 | arg = (long) nla_data(opt_data_attr); |
1397 | break; | 1414 | break; |
1415 | case TEAM_OPTION_TYPE_BINARY: | ||
1416 | tbinary.data_len = data_len; | ||
1417 | tbinary.data = nla_data(opt_data_attr); | ||
1418 | arg = (long) &tbinary; | ||
1419 | break; | ||
1398 | default: | 1420 | default: |
1399 | BUG(); | 1421 | BUG(); |
1400 | } | 1422 | } |
diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 58404b0c5010..41163ac14ab4 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h | |||
@@ -68,6 +68,7 @@ struct team_mode_ops { | |||
68 | enum team_option_type { | 68 | enum team_option_type { |
69 | TEAM_OPTION_TYPE_U32, | 69 | TEAM_OPTION_TYPE_U32, |
70 | TEAM_OPTION_TYPE_STRING, | 70 | TEAM_OPTION_TYPE_STRING, |
71 | TEAM_OPTION_TYPE_BINARY, | ||
71 | }; | 72 | }; |
72 | 73 | ||
73 | struct team_option { | 74 | struct team_option { |
@@ -82,6 +83,13 @@ struct team_option { | |||
82 | bool removed; | 83 | bool removed; |
83 | }; | 84 | }; |
84 | 85 | ||
86 | struct team_option_binary { | ||
87 | u32 data_len; | ||
88 | void *data; | ||
89 | }; | ||
90 | |||
91 | #define team_optarg_tbinary(arg) (*((struct team_option_binary **) arg)) | ||
92 | |||
85 | struct team_mode { | 93 | struct team_mode { |
86 | struct list_head list; | 94 | struct list_head list; |
87 | const char *kind; | 95 | const char *kind; |