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); |
