[Devel] [PATCH RH9 3/3] vzeth: bits and pieces of our interface
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Wed Oct 27 16:05:21 MSK 2021
From: Konstantin Khorenko <khorenko at virtuozzo.com>
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
Signed-off-by: Andrew Vagin <avagin at openvz.org>
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
vz9 changes:
- remove excess vzctl_veth.h
- remove excess include of br_private.h
- put everything under CONFIG_VE
https://jira.sw.ru/browse/PSBM-135200
(cherry picked from vz8 commit c4c1af66f15295e64ba722219bfb7838a46ec510)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
drivers/net/veth.c | 84 ++++++++++++++++++++++++++++++++-
include/linux/netdev_features.h | 2 +
include/uapi/linux/veth.h | 3 ++
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index bdb7ce3cb054..900a8868e6ce 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -294,6 +294,33 @@ static int veth_forward_skb(struct net_device *dev, struct sk_buff *skb,
netif_rx(skb);
}
+#ifdef CONFIG_VE
+static int vzethdev_filter(struct sk_buff *skb, struct net_device *dev, struct net_device *rcv)
+{
+ /* Filtering */
+ if (ve_is_super(dev_net(dev)->owner_ve) &&
+ dev->ve_features & NETIF_F_FIXED_ADDR) {
+ /* from VE0 to VEX */
+ if (ve_is_super(dev_net(rcv)->owner_ve))
+ return 1;
+ if (is_multicast_ether_addr(
+ ((struct ethhdr *)skb->data)->h_dest))
+ return 1;
+ if (!ether_addr_equal(((struct ethhdr *)skb->data)->h_dest,
+ rcv->dev_addr))
+ return 0;
+ } else if (!ve_is_super(dev_net(dev)->owner_ve) &&
+ dev->ve_features & NETIF_F_FIXED_ADDR) {
+ /* from VEX to VE0 */
+ if (!ether_addr_equal(((struct ethhdr *)skb->data)->h_source,
+ dev->dev_addr))
+ return 0;
+ }
+
+ return 1;
+}
+#endif
+
/* return true if the specified skb has chances of GRO aggregation
* Don't strive for accuracy, but try to avoid GRO overhead in the most
* common scenarios.
@@ -329,6 +356,13 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop;
}
+#ifdef CONFIG_VE
+ if (dev->ve_features & NETIF_F_VENET && !vzethdev_filter(skb, dev, rcv)) {
+ kfree_skb(skb);
+ goto drop;
+ }
+#endif
+
rcv_priv = netdev_priv(rcv);
rxq = skb_get_queue_mapping(skb);
if (rxq < rcv->real_num_rx_queues) {
@@ -1364,6 +1398,46 @@ static int veth_xdp(struct net_device *dev, struct netdev_bpf *xdp)
}
}
+#ifdef CONFIG_VE
+static int veth_mac_addr(struct net_device *dev, void *p)
+{
+ if (dev->ve_features & NETIF_F_VENET &&
+ dev->ve_features & NETIF_F_FIXED_ADDR)
+ return -EPERM;
+ return eth_mac_addr(dev, p);
+}
+
+static int vzethdev_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ switch (cmd) {
+ case SIOCSVENET:
+ {
+ struct veth_priv *priv = netdev_priv(dev);
+ struct net_device *rcv;
+
+ rcu_read_lock();
+ rcv = rcu_dereference(priv->peer);
+ if (rcv)
+ rcv->ve_features |= NETIF_F_VENET;
+ dev->ve_features |= NETIF_F_VENET;
+ rcu_read_unlock();
+
+ return 0;
+ }
+ case SIOCSFIXEDADDR:
+ if (ifr->ifr_ifru.ifru_flags)
+ dev->ve_features |= NETIF_F_FIXED_ADDR;
+ else
+ dev->ve_features &= ~NETIF_F_FIXED_ADDR;
+ return 0;
+ }
+ return -ENOTTY;
+}
+#endif
+
static const struct net_device_ops veth_netdev_ops = {
.ndo_init = veth_dev_init,
.ndo_open = veth_open,
@@ -1371,7 +1445,6 @@ static const struct net_device_ops veth_netdev_ops = {
.ndo_start_xmit = veth_xmit,
.ndo_get_stats64 = veth_get_stats64,
.ndo_set_rx_mode = veth_set_multicast_list,
- .ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = veth_poll_controller,
#endif
@@ -1383,6 +1456,12 @@ static const struct net_device_ops veth_netdev_ops = {
.ndo_bpf = veth_xdp,
.ndo_xdp_xmit = veth_ndo_xdp_xmit,
.ndo_get_peer_dev = veth_peer_dev,
+#ifdef CONFIG_VE
+ .ndo_set_mac_address = veth_mac_addr,
+ .ndo_do_ioctl = vzethdev_net_ioctl,
+#else
+ .ndo_set_mac_address = eth_mac_addr,
+#endif
};
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \
@@ -1404,6 +1483,9 @@ static void veth_setup(struct net_device *dev)
dev->ethtool_ops = &veth_ethtool_ops;
dev->features |= NETIF_F_LLTX;
dev->features |= VETH_FEATURES;
+#ifdef CONFIG_VE
+ dev->ve_features = NETIF_F_VIRTUAL;
+#endif
dev->vlan_features = dev->features &
~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX |
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 9945162fa074..22789112fa5b 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -172,10 +172,12 @@ enum {
enum {
NETIF_F_VIRTUAL_BIT, /* Device is venet device */
NETIF_F_VENET_BIT, /* Device is venet device */
+ NETIF_F_FIXED_ADDR_BIT, /* Device has fixed mac */
};
#define NETIF_F_VIRTUAL __NETIF_F(VIRTUAL)
#define NETIF_F_VENET __NETIF_F(VENET)
+#define NETIF_F_FIXED_ADDR __NETIF_F(FIXED_ADDR)
#endif
/* Finds the next feature with the highest number of the range of start till 0.
diff --git a/include/uapi/linux/veth.h b/include/uapi/linux/veth.h
index 52b58e587e23..ccc020590969 100644
--- a/include/uapi/linux/veth.h
+++ b/include/uapi/linux/veth.h
@@ -10,4 +10,7 @@ enum {
#define VETH_INFO_MAX (__VETH_INFO_MAX - 1)
};
+#define SIOCSVENET (SIOCDEVPRIVATE + 0xf)
+#define SIOCSFIXEDADDR (SIOCDEVPRIVATE + 0xe)
+
#endif
--
2.31.1
More information about the Devel
mailing list