aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2012-04-04 08:16:26 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-04 20:30:40 -0400
commit2615598fc100451c71b83d06bdf5faead619a40e (patch)
treed8df65665fecf7dfd25d42ba862c6f929be43ca3
parentbd856615c128c40d189d6dd68dde7afe15ed3446 (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.c30
-rw-r--r--include/linux/if_team.h8
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
1154static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) 1151static 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 {
68enum team_option_type { 68enum 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
73struct team_option { 74struct team_option {
@@ -82,6 +83,13 @@ struct team_option {
82 bool removed; 83 bool removed;
83}; 84};
84 85
86struct team_option_binary {
87 u32 data_len;
88 void *data;
89};
90
91#define team_optarg_tbinary(arg) (*((struct team_option_binary **) arg))
92
85struct team_mode { 93struct team_mode {
86 struct list_head list; 94 struct list_head list;
87 const char *kind; 95 const char *kind;