diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r-- | net/openvswitch/datapath.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 50d7782d8d7c..6a9b0cb8a1db 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1040,6 +1040,7 @@ static const struct genl_ops dp_flow_genl_ops[] = { | |||
1040 | static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = { | 1040 | static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = { |
1041 | [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, | 1041 | [OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, |
1042 | [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 }, | 1042 | [OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 }, |
1043 | [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, | ||
1043 | }; | 1044 | }; |
1044 | 1045 | ||
1045 | static struct genl_family dp_datapath_genl_family = { | 1046 | static struct genl_family dp_datapath_genl_family = { |
@@ -1098,6 +1099,9 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, | |||
1098 | &dp_megaflow_stats)) | 1099 | &dp_megaflow_stats)) |
1099 | goto nla_put_failure; | 1100 | goto nla_put_failure; |
1100 | 1101 | ||
1102 | if (nla_put_u32(skb, OVS_DP_ATTR_USER_FEATURES, dp->user_features)) | ||
1103 | goto nla_put_failure; | ||
1104 | |||
1101 | return genlmsg_end(skb, ovs_header); | 1105 | return genlmsg_end(skb, ovs_header); |
1102 | 1106 | ||
1103 | nla_put_failure: | 1107 | nla_put_failure: |
@@ -1144,6 +1148,12 @@ static struct datapath *lookup_datapath(struct net *net, | |||
1144 | return dp ? dp : ERR_PTR(-ENODEV); | 1148 | return dp ? dp : ERR_PTR(-ENODEV); |
1145 | } | 1149 | } |
1146 | 1150 | ||
1151 | static void ovs_dp_change(struct datapath *dp, struct nlattr **a) | ||
1152 | { | ||
1153 | if (a[OVS_DP_ATTR_USER_FEATURES]) | ||
1154 | dp->user_features = nla_get_u32(a[OVS_DP_ATTR_USER_FEATURES]); | ||
1155 | } | ||
1156 | |||
1147 | static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | 1157 | static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) |
1148 | { | 1158 | { |
1149 | struct nlattr **a = info->attrs; | 1159 | struct nlattr **a = info->attrs; |
@@ -1202,6 +1212,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1202 | parms.port_no = OVSP_LOCAL; | 1212 | parms.port_no = OVSP_LOCAL; |
1203 | parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]); | 1213 | parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]); |
1204 | 1214 | ||
1215 | ovs_dp_change(dp, a); | ||
1216 | |||
1205 | vport = new_vport(&parms); | 1217 | vport = new_vport(&parms); |
1206 | if (IS_ERR(vport)) { | 1218 | if (IS_ERR(vport)) { |
1207 | err = PTR_ERR(vport); | 1219 | err = PTR_ERR(vport); |
@@ -1305,6 +1317,8 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
1305 | if (IS_ERR(dp)) | 1317 | if (IS_ERR(dp)) |
1306 | goto unlock; | 1318 | goto unlock; |
1307 | 1319 | ||
1320 | ovs_dp_change(dp, info->attrs); | ||
1321 | |||
1308 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW); | 1322 | reply = ovs_dp_cmd_build_info(dp, info, OVS_DP_CMD_NEW); |
1309 | if (IS_ERR(reply)) { | 1323 | if (IS_ERR(reply)) { |
1310 | err = PTR_ERR(reply); | 1324 | err = PTR_ERR(reply); |