Commit 1bdc0b10 authored by David S. Miller's avatar David S. Miller

Merge branch 'vxlan-fixes'

Jiri Benc says:

====================
vxlan fixes

This fixes various issues with vxlan related to IPv6.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c38f6ac7 ac7eccd4
......@@ -1946,6 +1946,7 @@ struct bnx2x {
u16 vlan_cnt;
u16 vlan_credit;
u16 vxlan_dst_port;
u8 vxlan_dst_port_count;
bool accept_any_vlan;
};
......
......@@ -10108,12 +10108,18 @@ static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port)
if (!netif_running(bp->dev))
return;
if (bp->vxlan_dst_port || !IS_PF(bp)) {
if (bp->vxlan_dst_port_count && bp->vxlan_dst_port == port) {
bp->vxlan_dst_port_count++;
return;
}
if (bp->vxlan_dst_port_count || !IS_PF(bp)) {
DP(BNX2X_MSG_SP, "Vxlan destination port limit reached\n");
return;
}
bp->vxlan_dst_port = port;
bp->vxlan_dst_port_count = 1;
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_ADD_VXLAN_PORT, 0);
}
......@@ -10128,10 +10134,14 @@ static void bnx2x_add_vxlan_port(struct net_device *netdev,
static void __bnx2x_del_vxlan_port(struct bnx2x *bp, u16 port)
{
if (!bp->vxlan_dst_port || bp->vxlan_dst_port != port || !IS_PF(bp)) {
if (!bp->vxlan_dst_port_count || bp->vxlan_dst_port != port ||
!IS_PF(bp)) {
DP(BNX2X_MSG_SP, "Invalid vxlan port\n");
return;
}
bp->vxlan_dst_port--;
if (bp->vxlan_dst_port)
return;
if (netif_running(bp->dev)) {
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_DEL_VXLAN_PORT, 0);
......
......@@ -582,6 +582,7 @@ struct be_adapter {
u16 pvid;
__be16 vxlan_port;
int vxlan_port_count;
int vxlan_port_aliases;
struct phy_info phy;
u8 wol_cap;
bool wol_en;
......
......@@ -5176,6 +5176,11 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family,
if (lancer_chip(adapter) || BEx_chip(adapter) || be_is_mc(adapter))
return;
if (adapter->vxlan_port == port && adapter->vxlan_port_count) {
adapter->vxlan_port_aliases++;
return;
}
if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) {
dev_info(dev,
"Only one UDP port supported for VxLAN offloads\n");
......@@ -5226,6 +5231,11 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family,
if (adapter->vxlan_port != port)
goto done;
if (adapter->vxlan_port_aliases) {
adapter->vxlan_port_aliases--;
return;
}
be_disable_vxlan_offloads(adapter);
dev_info(&adapter->pdev->dev,
......
......@@ -536,6 +536,7 @@ struct qlcnic_hardware_context {
u8 extend_lb_time;
u8 phys_port_id[ETH_ALEN];
u8 lb_mode;
u8 vxlan_port_count;
u16 vxlan_port;
struct device *hwmon_dev;
u32 post_mode;
......
......@@ -483,11 +483,17 @@ static void qlcnic_add_vxlan_port(struct net_device *netdev,
/* Adapter supports only one VXLAN port. Use very first port
* for enabling offload
*/
if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port)
if (!qlcnic_encap_rx_offload(adapter))
return;
if (!ahw->vxlan_port_count) {
ahw->vxlan_port_count = 1;
ahw->vxlan_port = ntohs(port);
adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
return;
}
if (ahw->vxlan_port == ntohs(port))
ahw->vxlan_port_count++;
ahw->vxlan_port = ntohs(port);
adapter->flags |= QLCNIC_ADD_VXLAN_PORT;
}
static void qlcnic_del_vxlan_port(struct net_device *netdev,
......@@ -496,11 +502,13 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev,
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_hardware_context *ahw = adapter->ahw;
if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port ||
if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port_count ||
(ahw->vxlan_port != ntohs(port)))
return;
adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
ahw->vxlan_port_count--;
if (!ahw->vxlan_port_count)
adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
}
static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
......
......@@ -2392,10 +2392,6 @@ static void vxlan_setup(struct net_device *dev)
eth_hw_addr_random(dev);
ether_setup(dev);
if (vxlan->default_dst.remote_ip.sa.sa_family == AF_INET6)
dev->needed_headroom = ETH_HLEN + VXLAN6_HEADROOM;
else
dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM;
dev->netdev_ops = &vxlan_netdev_ops;
dev->destructor = free_netdev;
......@@ -2640,8 +2636,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
dst->remote_ip.sa.sa_family = AF_INET;
if (dst->remote_ip.sa.sa_family == AF_INET6 ||
vxlan->cfg.saddr.sa.sa_family == AF_INET6)
vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
if (!IS_ENABLED(CONFIG_IPV6))
return -EPFNOSUPPORT;
use_ipv6 = true;
}
if (conf->remote_ifindex) {
struct net_device *lowerdev
......@@ -2670,8 +2669,12 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
dev->needed_headroom = lowerdev->hard_header_len +
(use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
} else if (use_ipv6)
} else if (use_ipv6) {
vxlan->flags |= VXLAN_F_IPV6;
dev->needed_headroom = ETH_HLEN + VXLAN6_HEADROOM;
} else {
dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM;
}
memcpy(&vxlan->cfg, conf, sizeof(*conf));
if (!vxlan->cfg.dst_port)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment