Skip to content

Commit

Permalink
openvswitch: allow specifying ifindex of new interfaces
Browse files Browse the repository at this point in the history
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: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
azhadchenko authored and kuba-moo committed Aug 27, 2022
1 parent f7650d8 commit 54c4ef3
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/uapi/linux/openvswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ enum ovs_datapath_cmd {
* datapath. Always present in notifications.
* @OVS_DP_ATTR_MEGAFLOW_STATS: Statistics about mega flow masks usage for the
* 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
* payload for %OVS_DP_* commands.
Expand All @@ -92,6 +94,7 @@ enum ovs_datapath_attr {
OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in
* per-cpu dispatch mode
*/
OVS_DP_ATTR_IFINDEX,
__OVS_DP_ATTR_MAX
};

Expand Down
11 changes: 9 additions & 2 deletions net/openvswitch/datapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
parms.dp = dp;
parms.port_no = OVSP_LOCAL;
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. */
ovs_lock();
Expand Down Expand Up @@ -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_MASKS_CACHE_SIZE] = NLA_POLICY_RANGE(NLA_U32, 0,
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[] = {
Expand Down Expand Up @@ -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] ||
!a[OVS_VPORT_ATTR_UPCALL_PID])
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;

port_no = a[OVS_VPORT_ATTR_PORT_NO]
Expand Down Expand Up @@ -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.type = nla_get_u32(a[OVS_VPORT_ATTR_TYPE]);
parms.options = a[OVS_VPORT_ATTR_OPTIONS];
parms.dp = dp;
parms.port_no = port_no;
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);
err = PTR_ERR(vport);
Expand Down
1 change: 1 addition & 0 deletions net/openvswitch/vport-internal_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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->ifindex = parms->desired_ifindex;
internal_dev = internal_dev_priv(vport->dev);
internal_dev->vport = vport;

Expand Down
2 changes: 2 additions & 0 deletions net/openvswitch/vport.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ struct vport {
* @type: New vport's type.
* @options: %OVS_VPORT_ATTR_OPTIONS attribute from Netlink message, %NULL if
* none was supplied.
* @desired_ifindex: New vport's ifindex.
* @dp: New vport's datapath.
* @port_no: New vport's port number.
*/
struct vport_parms {
const char *name;
enum ovs_vport_type type;
int desired_ifindex;
struct nlattr *options;

/* For ovs_vport_alloc(). */
Expand Down

0 comments on commit 54c4ef3

Please sign in to comment.