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 rh9-5.14.0-4.vz9.10.20
------>
commit 9eb81eca18c3aa4c617cddc9e4f312e6ba1cfbe4
Author: Konstantin Khorenko <khore...@virtuozzo.com>
Date:   Wed Oct 27 19:07:43 2021 +0300

    vzeth: bits and pieces of our interface
    
    Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com>
    Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org>
    Signed-off-by: Stanislav Kinsbursky <skinsbur...@parallels.com>
    Signed-off-by: Andrew Vagin <ava...@openvz.org>
    Signed-off-by: Vladimir Davydov <vdavy...@parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcu...@openvz.org>
    
    vz9 changes:
    - remove excess vzctl_veth.h
    - remove excess include of br_private.h
    - put everything under CONFIG_VE
    
    v2: cleanup vzethdev_filter
    
    https://jira.sw.ru/browse/PSBM-135200
    (cherry picked from vz8 commit c4c1af66f15295e64ba722219bfb7838a46ec510)
    Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>
---
 drivers/net/veth.c              | 85 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/netdev_features.h |  2 +
 include/uapi/linux/veth.h       |  3 ++
 3 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index bdb7ce3cb054..1ccd8e7ed0f1 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -294,6 +294,34 @@ 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)
+{
+       struct ethhdr *eh;
+
+       if (!(dev->ve_features & NETIF_F_FIXED_ADDR))
+               return 1;
+
+       /* Filtering */
+       eh = (struct ethhdr *)skb->data;
+       if (ve_is_super(dev_net(dev)->owner_ve)) {
+               /* from VE0 to VEX */
+               if (ve_is_super(dev_net(rcv)->owner_ve))
+                       return 1;
+               if (is_multicast_ether_addr(eh->h_dest))
+                       return 1;
+               if (!ether_addr_equal(eh->h_dest, rcv->dev_addr))
+                       return 0;
+       } else {
+               /* from VEX to VE0 */
+               if (!ether_addr_equal(eh->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 +357,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 +1399,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 +1446,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 +1457,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 +1484,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 166a1ef48774..7cff8a5c750f 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -172,10 +172,12 @@ enum {
 enum {
        NETIF_F_VIRTUAL_BIT,    /* Can be registered inside VE */
        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
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to