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 { ...@@ -1946,6 +1946,7 @@ struct bnx2x {
u16 vlan_cnt; u16 vlan_cnt;
u16 vlan_credit; u16 vlan_credit;
u16 vxlan_dst_port; u16 vxlan_dst_port;
u8 vxlan_dst_port_count;
bool accept_any_vlan; bool accept_any_vlan;
}; };
......
...@@ -10108,12 +10108,18 @@ static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port) ...@@ -10108,12 +10108,18 @@ static void __bnx2x_add_vxlan_port(struct bnx2x *bp, u16 port)
if (!netif_running(bp->dev)) if (!netif_running(bp->dev))
return; 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"); DP(BNX2X_MSG_SP, "Vxlan destination port limit reached\n");
return; return;
} }
bp->vxlan_dst_port = port; bp->vxlan_dst_port = port;
bp->vxlan_dst_port_count = 1;
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_ADD_VXLAN_PORT, 0); 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, ...@@ -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) 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"); DP(BNX2X_MSG_SP, "Invalid vxlan port\n");
return; return;
} }
bp->vxlan_dst_port--;
if (bp->vxlan_dst_port)
return;
if (netif_running(bp->dev)) { if (netif_running(bp->dev)) {
bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_DEL_VXLAN_PORT, 0); bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_DEL_VXLAN_PORT, 0);
......
...@@ -582,6 +582,7 @@ struct be_adapter { ...@@ -582,6 +582,7 @@ struct be_adapter {
u16 pvid; u16 pvid;
__be16 vxlan_port; __be16 vxlan_port;
int vxlan_port_count; int vxlan_port_count;
int vxlan_port_aliases;
struct phy_info phy; struct phy_info phy;
u8 wol_cap; u8 wol_cap;
bool wol_en; bool wol_en;
......
...@@ -5176,6 +5176,11 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, ...@@ -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)) if (lancer_chip(adapter) || BEx_chip(adapter) || be_is_mc(adapter))
return; return;
if (adapter->vxlan_port == port && adapter->vxlan_port_count) {
adapter->vxlan_port_aliases++;
return;
}
if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) { if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) {
dev_info(dev, dev_info(dev,
"Only one UDP port supported for VxLAN offloads\n"); "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, ...@@ -5226,6 +5231,11 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family,
if (adapter->vxlan_port != port) if (adapter->vxlan_port != port)
goto done; goto done;
if (adapter->vxlan_port_aliases) {
adapter->vxlan_port_aliases--;
return;
}
be_disable_vxlan_offloads(adapter); be_disable_vxlan_offloads(adapter);
dev_info(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
......
...@@ -536,6 +536,7 @@ struct qlcnic_hardware_context { ...@@ -536,6 +536,7 @@ struct qlcnic_hardware_context {
u8 extend_lb_time; u8 extend_lb_time;
u8 phys_port_id[ETH_ALEN]; u8 phys_port_id[ETH_ALEN];
u8 lb_mode; u8 lb_mode;
u8 vxlan_port_count;
u16 vxlan_port; u16 vxlan_port;
struct device *hwmon_dev; struct device *hwmon_dev;
u32 post_mode; u32 post_mode;
......
...@@ -483,11 +483,17 @@ static void qlcnic_add_vxlan_port(struct net_device *netdev, ...@@ -483,11 +483,17 @@ static void qlcnic_add_vxlan_port(struct net_device *netdev,
/* Adapter supports only one VXLAN port. Use very first port /* Adapter supports only one VXLAN port. Use very first port
* for enabling offload * for enabling offload
*/ */
if (!qlcnic_encap_rx_offload(adapter) || ahw->vxlan_port) if (!qlcnic_encap_rx_offload(adapter))
return; 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, static void qlcnic_del_vxlan_port(struct net_device *netdev,
...@@ -496,11 +502,13 @@ 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_adapter *adapter = netdev_priv(netdev);
struct qlcnic_hardware_context *ahw = adapter->ahw; 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))) (ahw->vxlan_port != ntohs(port)))
return; 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, static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
......
...@@ -2392,10 +2392,6 @@ static void vxlan_setup(struct net_device *dev) ...@@ -2392,10 +2392,6 @@ static void vxlan_setup(struct net_device *dev)
eth_hw_addr_random(dev); eth_hw_addr_random(dev);
ether_setup(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->netdev_ops = &vxlan_netdev_ops;
dev->destructor = free_netdev; dev->destructor = free_netdev;
...@@ -2640,8 +2636,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, ...@@ -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; dst->remote_ip.sa.sa_family = AF_INET;
if (dst->remote_ip.sa.sa_family == AF_INET6 || 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; use_ipv6 = true;
}
if (conf->remote_ifindex) { if (conf->remote_ifindex) {
struct net_device *lowerdev struct net_device *lowerdev
...@@ -2670,8 +2669,12 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, ...@@ -2670,8 +2669,12 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
dev->needed_headroom = lowerdev->hard_header_len + dev->needed_headroom = lowerdev->hard_header_len +
(use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
} else if (use_ipv6) } else if (use_ipv6) {
vxlan->flags |= VXLAN_F_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)); memcpy(&vxlan->cfg, conf, sizeof(*conf));
if (!vxlan->cfg.dst_port) 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