Skip to content

Commit 9354d45

Browse files
Jiri Bencdavem330
authored andcommitted
openvswitch: reliable interface indentification in port dumps
This patch allows reliable identification of netdevice interfaces connected to openvswitch bridges. In particular, user space queries the netdev interfaces belonging to the ports for statistics, up/down state, etc. Datapath dump needs to provide enough information for the user space to be able to do that. Currently, only interface names are returned. This is not sufficient, as openvswitch allows its ports to be in different name spaces and the interface name is valid only in its name space. What is needed and generally used in other netlink APIs, is the pair ifindex+netnsid. The solution is addition of the ifindex+netnsid pair (or only ifindex if in the same name space) to vport get/dump operation. On request side, ideally the ifindex+netnsid pair could be used to get/set/del the corresponding vport. This is not implemented by this patch and can be added later if needed. Signed-off-by: Jiri Benc <jbenc@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 7cbebc8 commit 9354d45

File tree

4 files changed

+40
-17
lines changed

4 files changed

+40
-17
lines changed

include/uapi/linux/openvswitch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ enum ovs_vport_attr {
258258
/* receiving upcalls */
259259
OVS_VPORT_ATTR_STATS, /* struct ovs_vport_stats */
260260
OVS_VPORT_ATTR_PAD,
261+
OVS_VPORT_ATTR_IFINDEX,
262+
OVS_VPORT_ATTR_NETNSID,
261263
__OVS_VPORT_ATTR_MAX
262264
};
263265

net/openvswitch/datapath.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,7 +1848,8 @@ static struct genl_family dp_datapath_genl_family __ro_after_init = {
18481848

18491849
/* Called with ovs_mutex or RCU read lock. */
18501850
static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1851-
u32 portid, u32 seq, u32 flags, u8 cmd)
1851+
struct net *net, u32 portid, u32 seq,
1852+
u32 flags, u8 cmd)
18521853
{
18531854
struct ovs_header *ovs_header;
18541855
struct ovs_vport_stats vport_stats;
@@ -1864,9 +1865,17 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
18641865
if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
18651866
nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
18661867
nla_put_string(skb, OVS_VPORT_ATTR_NAME,
1867-
ovs_vport_name(vport)))
1868+
ovs_vport_name(vport)) ||
1869+
nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
18681870
goto nla_put_failure;
18691871

1872+
if (!net_eq(net, dev_net(vport->dev))) {
1873+
int id = peernet2id_alloc(net, dev_net(vport->dev));
1874+
1875+
if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
1876+
goto nla_put_failure;
1877+
}
1878+
18701879
ovs_vport_get_stats(vport, &vport_stats);
18711880
if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
18721881
sizeof(struct ovs_vport_stats), &vport_stats,
@@ -1896,8 +1905,8 @@ static struct sk_buff *ovs_vport_cmd_alloc_info(void)
18961905
}
18971906

18981907
/* Called with ovs_mutex, only via ovs_dp_notify_wq(). */
1899-
struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
1900-
u32 seq, u8 cmd)
1908+
struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, struct net *net,
1909+
u32 portid, u32 seq, u8 cmd)
19011910
{
19021911
struct sk_buff *skb;
19031912
int retval;
@@ -1906,7 +1915,7 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
19061915
if (!skb)
19071916
return ERR_PTR(-ENOMEM);
19081917

1909-
retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
1918+
retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd);
19101919
BUG_ON(retval < 0);
19111920

19121921
return skb;
@@ -1920,6 +1929,8 @@ static struct vport *lookup_vport(struct net *net,
19201929
struct datapath *dp;
19211930
struct vport *vport;
19221931

1932+
if (a[OVS_VPORT_ATTR_IFINDEX])
1933+
return ERR_PTR(-EOPNOTSUPP);
19231934
if (a[OVS_VPORT_ATTR_NAME]) {
19241935
vport = ovs_vport_locate(net, nla_data(a[OVS_VPORT_ATTR_NAME]));
19251936
if (!vport)
@@ -1944,6 +1955,7 @@ static struct vport *lookup_vport(struct net *net,
19441955
return vport;
19451956
} else
19461957
return ERR_PTR(-EINVAL);
1958+
19471959
}
19481960

19491961
/* Called with ovs_mutex */
@@ -1983,6 +1995,8 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
19831995
if (!a[OVS_VPORT_ATTR_NAME] || !a[OVS_VPORT_ATTR_TYPE] ||
19841996
!a[OVS_VPORT_ATTR_UPCALL_PID])
19851997
return -EINVAL;
1998+
if (a[OVS_VPORT_ATTR_IFINDEX])
1999+
return -EOPNOTSUPP;
19862000

19872001
port_no = a[OVS_VPORT_ATTR_PORT_NO]
19882002
? nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]) : 0;
@@ -2032,8 +2046,9 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
20322046
goto exit_unlock_free;
20332047
}
20342048

2035-
err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
2036-
info->snd_seq, 0, OVS_VPORT_CMD_NEW);
2049+
err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
2050+
info->snd_portid, info->snd_seq, 0,
2051+
OVS_VPORT_CMD_NEW);
20372052

20382053
if (netdev_get_fwd_headroom(vport->dev) > dp->max_headroom)
20392054
update_headroom(dp);
@@ -2090,8 +2105,9 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
20902105
goto exit_unlock_free;
20912106
}
20922107

2093-
err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
2094-
info->snd_seq, 0, OVS_VPORT_CMD_NEW);
2108+
err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
2109+
info->snd_portid, info->snd_seq, 0,
2110+
OVS_VPORT_CMD_NEW);
20952111
BUG_ON(err < 0);
20962112

20972113
ovs_unlock();
@@ -2128,8 +2144,9 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
21282144
goto exit_unlock_free;
21292145
}
21302146

2131-
err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
2132-
info->snd_seq, 0, OVS_VPORT_CMD_DEL);
2147+
err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
2148+
info->snd_portid, info->snd_seq, 0,
2149+
OVS_VPORT_CMD_DEL);
21332150
BUG_ON(err < 0);
21342151

21352152
/* the vport deletion may trigger dp headroom update */
@@ -2169,8 +2186,9 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
21692186
err = PTR_ERR(vport);
21702187
if (IS_ERR(vport))
21712188
goto exit_unlock_free;
2172-
err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
2173-
info->snd_seq, 0, OVS_VPORT_CMD_NEW);
2189+
err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
2190+
info->snd_portid, info->snd_seq, 0,
2191+
OVS_VPORT_CMD_NEW);
21742192
BUG_ON(err < 0);
21752193
rcu_read_unlock();
21762194

@@ -2202,6 +2220,7 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
22022220
hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) {
22032221
if (j >= skip &&
22042222
ovs_vport_cmd_fill_info(vport, skb,
2223+
sock_net(skb->sk),
22052224
NETLINK_CB(cb->skb).portid,
22062225
cb->nlh->nlmsg_seq,
22072226
NLM_F_MULTI,
@@ -2228,6 +2247,8 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
22282247
[OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
22292248
[OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_U32 },
22302249
[OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
2250+
[OVS_VPORT_ATTR_IFINDEX] = { .type = NLA_U32 },
2251+
[OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 },
22312252
};
22322253

22332254
static const struct genl_ops dp_vport_genl_ops[] = {

net/openvswitch/datapath.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ int ovs_dp_upcall(struct datapath *, struct sk_buff *,
200200
uint32_t cutlen);
201201

202202
const char *ovs_dp_name(const struct datapath *dp);
203-
struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq,
204-
u8 cmd);
203+
struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, struct net *net,
204+
u32 portid, u32 seq, u8 cmd);
205205

206206
int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
207207
const struct sw_flow_actions *, struct sw_flow_key *);

net/openvswitch/dp_notify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ static void dp_detach_port_notify(struct vport *vport)
3030
struct datapath *dp;
3131

3232
dp = vport->dp;
33-
notify = ovs_vport_cmd_build_info(vport, 0, 0,
34-
OVS_VPORT_CMD_DEL);
33+
notify = ovs_vport_cmd_build_info(vport, ovs_dp_get_net(dp),
34+
0, 0, OVS_VPORT_CMD_DEL);
3535
ovs_dp_detach_port(vport);
3636
if (IS_ERR(notify)) {
3737
genl_set_err(&dp_vport_genl_family, ovs_dp_get_net(dp), 0,

0 commit comments

Comments
 (0)