Commit 54c4ef34 authored by Andrey Zhadchenko's avatar Andrey Zhadchenko Committed by Jakub Kicinski

openvswitch: allow specifying ifindex of new interfaces

CRIU is preserving ifindexes of net devices after restoration. However,
current Open vSwitch API does not allow to target ifindex, so we cannot
correctly restore OVS configuration.

Add new OVS_DP_ATTR_IFINDEX for OVS_DP_CMD_NEW and use it as desired
ifindex.
Use OVS_VPORT_ATTR_IFINDEX during OVS_VPORT_CMD_NEW to specify new netdev
ifindex.
Signed-off-by: default avatarAndrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
Acked-by: default avatarChristian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f7650d82
...@@ -76,6 +76,8 @@ enum ovs_datapath_cmd { ...@@ -76,6 +76,8 @@ enum ovs_datapath_cmd {
* datapath. Always present in notifications. * datapath. Always present in notifications.
* @OVS_DP_ATTR_MEGAFLOW_STATS: Statistics about mega flow masks usage for the * @OVS_DP_ATTR_MEGAFLOW_STATS: Statistics about mega flow masks usage for the
* datapath. Always present in notifications. * datapath. Always present in notifications.
* @OVS_DP_ATTR_IFINDEX: Interface index for a new datapath netdev. Only
* valid for %OVS_DP_CMD_NEW requests.
* *
* These attributes follow the &struct ovs_header within the Generic Netlink * These attributes follow the &struct ovs_header within the Generic Netlink
* payload for %OVS_DP_* commands. * payload for %OVS_DP_* commands.
...@@ -92,6 +94,7 @@ enum ovs_datapath_attr { ...@@ -92,6 +94,7 @@ enum ovs_datapath_attr {
OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in
* per-cpu dispatch mode * per-cpu dispatch mode
*/ */
OVS_DP_ATTR_IFINDEX,
__OVS_DP_ATTR_MAX __OVS_DP_ATTR_MAX
}; };
......
...@@ -1787,6 +1787,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) ...@@ -1787,6 +1787,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
parms.dp = dp; parms.dp = dp;
parms.port_no = OVSP_LOCAL; parms.port_no = OVSP_LOCAL;
parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID]; parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
parms.desired_ifindex = a[OVS_DP_ATTR_IFINDEX]
? nla_get_u32(a[OVS_DP_ATTR_IFINDEX]) : 0;
/* So far only local changes have been made, now need the lock. */ /* So far only local changes have been made, now need the lock. */
ovs_lock(); ovs_lock();
...@@ -2004,6 +2006,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = { ...@@ -2004,6 +2006,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
[OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
[OVS_DP_ATTR_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0, [OVS_DP_ATTR_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0,
PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)), PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)),
[OVS_DP_ATTR_IFINDEX] = {.type = NLA_U32 },
}; };
static const struct genl_small_ops dp_datapath_genl_ops[] = { static const struct genl_small_ops dp_datapath_genl_ops[] = {
...@@ -2207,7 +2210,10 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) ...@@ -2207,7 +2210,10 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] || if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] ||
!a[OVS_VPORT_ATTR_UPCALL_PID]) !a[OVS_VPORT_ATTR_UPCALL_PID])
return -EINVAL; return -EINVAL;
if (a[OVS_VPORT_ATTR_IFINDEX])
parms.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
if (a[OVS_VPORT_ATTR_IFINDEX] && parms.type != OVS_VPORT_TYPE_INTERNAL)
return -EOPNOTSUPP; return -EOPNOTSUPP;
port_no = a[OVS_VPORT_ATTR_PORT_NO] port_no = a[OVS_VPORT_ATTR_PORT_NO]
...@@ -2244,11 +2250,12 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) ...@@ -2244,11 +2250,12 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
} }
parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]); parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]);
parms.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
parms.options = a[OVS_VPORT_ATTR_OPTIONS]; parms.options = a[OVS_VPORT_ATTR_OPTIONS];
parms.dp = dp; parms.dp = dp;
parms.port_no = port_no; parms.port_no = port_no;
parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID]; parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
parms.desired_ifindex = a[OVS_VPORT_ATTR_IFINDEX]
? nla_get_u32(a[OVS_VPORT_ATTR_IFINDEX]) : 0;
vport = new_vport(&parms); vport = new_vport(&parms);
err = PTR_ERR(vport); err = PTR_ERR(vport);
......
...@@ -147,6 +147,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms) ...@@ -147,6 +147,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
} }
dev_net_set(vport->dev, ovs_dp_get_net(vport->dp)); dev_net_set(vport->dev, ovs_dp_get_net(vport->dp));
dev->ifindex = parms->desired_ifindex;
internal_dev = internal_dev_priv(vport->dev); internal_dev = internal_dev_priv(vport->dev);
internal_dev->vport = vport; internal_dev->vport = vport;
......
...@@ -90,12 +90,14 @@ struct vport { ...@@ -90,12 +90,14 @@ struct vport {
* @type: New vport's type. * @type: New vport's type.
* @options: %OVS_VPORT_ATTR_OPTIONS attribute from Netlink message, %NULL if * @options: %OVS_VPORT_ATTR_OPTIONS attribute from Netlink message, %NULL if
* none was supplied. * none was supplied.
* @desired_ifindex: New vport's ifindex.
* @dp: New vport's datapath. * @dp: New vport's datapath.
* @port_no: New vport's port number. * @port_no: New vport's port number.
*/ */
struct vport_parms { struct vport_parms {
const char *name; const char *name;
enum ovs_vport_type type; enum ovs_vport_type type;
int desired_ifindex;
struct nlattr *options; struct nlattr *options;
/* For ovs_vport_alloc(). */ /* For ovs_vport_alloc(). */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment