diff options
| -rw-r--r-- | include/uapi/linux/openvswitch.h | 4 | ||||
| -rw-r--r-- | net/openvswitch/datapath.c | 14 | ||||
| -rw-r--r-- | net/openvswitch/datapath.h | 2 |
3 files changed, 20 insertions, 0 deletions
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index d120f9fe0017..07ef2c3e21fa 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h | |||
| @@ -75,6 +75,7 @@ enum ovs_datapath_attr { | |||
| 75 | OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */ | 75 | OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */ |
| 76 | OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */ | 76 | OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */ |
| 77 | OVS_DP_ATTR_MEGAFLOW_STATS, /* struct ovs_dp_megaflow_stats */ | 77 | OVS_DP_ATTR_MEGAFLOW_STATS, /* struct ovs_dp_megaflow_stats */ |
| 78 | OVS_DP_ATTR_USER_FEATURES, /* OVS_DP_F_* */ | ||
| 78 | __OVS_DP_ATTR_MAX | 79 | __OVS_DP_ATTR_MAX |
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| @@ -106,6 +107,9 @@ struct ovs_vport_stats { | |||
| 106 | __u64 tx_dropped; /* no space available in linux */ | 107 | __u64 tx_dropped; /* no space available in linux */ |
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 110 | /* Allow last Netlink attribute to be unaligned */ | ||
| 111 | #define OVS_DP_F_UNALIGNED (1 << 0) | ||
| 112 | |||
| 109 | /* Fixed logical ports. */ | 113 | /* Fixed logical ports. */ |
| 110 | #define OVSP_LOCAL ((__u32)0) | 114 | #define OVSP_LOCAL ((__u32)0) |
| 111 | 115 | ||
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); |
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index ba13be4a680f..62619a4ee649 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
| @@ -88,6 +88,8 @@ struct datapath { | |||
| 88 | /* Network namespace ref. */ | 88 | /* Network namespace ref. */ |
| 89 | struct net *net; | 89 | struct net *net; |
| 90 | #endif | 90 | #endif |
| 91 | |||
| 92 | u32 user_features; | ||
| 91 | }; | 93 | }; |
| 92 | 94 | ||
| 93 | /** | 95 | /** |
