[Devel] [PATCH RHEL COMMIT] net: openvswitch: add capability to specify ifindex of new links
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Oct 12 16:18:24 MSK 2021
The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit a88f8a17773816e158d026af6ec499a97b698b83
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date: Tue Oct 12 16:18:24 2021 +0300
net: openvswitch: add capability to specify ifindex of new links
CRIU is preserving ifindexes of net devices after restoration, but
current Open vSwitch API are not capable to do that. So we need to
modify it, because
- Restoring net devices with random ifindex will lead to some excessive
work to restore master relationship.
- OVS device taking another link ifindex will likely cause some problems
and may snowball previous point.
- Although OVS daemon is not supported yet, it is holding some tables
which have ifindex.
Openvswitch creates several net devices, but unlike rtnetlink API there is
no option to specify ifindex for link. This is crucial for criu during
restore stage.
Use ovs_header->dp_ifindex during OVS_DP_CMD_NEW as desired ifindex.
Use OVS_VPORT_ATTR_IFINDEX during OVS_VPORT_CMD_NEW to specify new netdev
ifindex. Both values were not relevant for corresponding requests, so
existing software won't mess with it.
https://jira.sw.ru/browse/PSBM-105844
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
net/openvswitch/datapath.c | 16 ++++++++++++++--
net/openvswitch/vport-internal_dev.c | 1 +
net/openvswitch/vport.h | 2 ++
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index bc164b35e67d..d5b7d82e4696 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1666,6 +1666,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
struct vport *vport;
struct ovs_net *ovs_net;
int err;
+ struct ovs_header *ovs_header = info->userhdr;
err = -EINVAL;
if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
@@ -1706,6 +1707,7 @@ 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 = ovs_header->dp_ifindex;
/* So far only local changes have been made, now need the lock. */
ovs_lock();
@@ -2123,7 +2125,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]
@@ -2160,12 +2165,19 @@ 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];
+ if (parms.type == OVS_VPORT_TYPE_INTERNAL) {
+ if (a[OVS_VPORT_ATTR_IFINDEX])
+ parms.desired_ifindex =
+ nla_get_u32(a[OVS_VPORT_ATTR_IFINDEX]);
+ else
+ parms.desired_ifindex = 0;
+ }
+
vport = new_vport(&parms);
err = PTR_ERR(vport);
if (IS_ERR(vport)) {
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 5b2ee9c1c00b..2ab8a7e06d4b 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -154,6 +154,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
if (vport->port_no == OVSP_LOCAL)
vport->dev->features |= NETIF_F_NETNS_LOCAL;
+ dev->ifindex = parms->desired_ifindex;
rtnl_lock();
err = register_netdevice(vport->dev);
if (err)
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 8a930ca6d6b1..e505899ef4d7 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -96,6 +96,8 @@ struct vport_parms {
enum ovs_vport_type type;
struct nlattr *options;
+ int desired_ifindex;
+
/* For ovs_vport_alloc(). */
struct datapath *dp;
u16 port_no;
More information about the Devel
mailing list