From: Konstantin Khorenko <khore...@virtuozzo.com> 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 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 | 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 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel