Commit 2a8a1552 authored by Shannon Nelson's avatar Shannon Nelson Committed by Jeff Kirsher

ixgbe: check ipsec ip addr against mgmt filters

Make sure we don't try to offload the decryption of an incoming
packet that should get delivered to the management engine.  This
is a corner case that will likely be very seldom seen, but could
really confuse someone if they were to hit it.
Suggested-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarShannon Nelson <shannon.nelson@oracle.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 88adce4e
...@@ -444,6 +444,89 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs, ...@@ -444,6 +444,89 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
return 0; return 0;
} }
/**
* ixgbe_ipsec_check_mgmt_ip - make sure there is no clash with mgmt IP filters
* @xs: pointer to transformer state struct
**/
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
struct net_device *dev = xs->xso.dev;
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_hw *hw = &adapter->hw;
u32 mfval, manc, reg;
int num_filters = 4;
bool manc_ipv4;
u32 bmcipval;
int i, j;
#define MANC_EN_IPV4_FILTER BIT(24)
#define MFVAL_IPV4_FILTER_SHIFT 16
#define MFVAL_IPV6_FILTER_SHIFT 24
#define MIPAF_ARR(_m, _n) (IXGBE_MIPAF + ((_m) * 0x10) + ((_n) * 4))
#define IXGBE_BMCIP(_n) (0x5050 + ((_n) * 4))
#define IXGBE_BMCIPVAL 0x5060
#define BMCIP_V4 0x2
#define BMCIP_V6 0x3
#define BMCIP_MASK 0x3
manc = IXGBE_READ_REG(hw, IXGBE_MANC);
manc_ipv4 = !!(manc & MANC_EN_IPV4_FILTER);
mfval = IXGBE_READ_REG(hw, IXGBE_MFVAL);
bmcipval = IXGBE_READ_REG(hw, IXGBE_BMCIPVAL);
if (xs->props.family == AF_INET) {
/* are there any IPv4 filters to check? */
if (manc_ipv4) {
/* the 4 ipv4 filters are all in MIPAF(3, i) */
for (i = 0; i < num_filters; i++) {
if (!(mfval & BIT(MFVAL_IPV4_FILTER_SHIFT + i)))
continue;
reg = IXGBE_READ_REG(hw, MIPAF_ARR(3, i));
if (reg == xs->id.daddr.a4)
return 1;
}
}
if ((bmcipval & BMCIP_MASK) == BMCIP_V4) {
reg = IXGBE_READ_REG(hw, IXGBE_BMCIP(3));
if (reg == xs->id.daddr.a4)
return 1;
}
} else {
/* if there are ipv4 filters, they are in the last ipv6 slot */
if (manc_ipv4)
num_filters = 3;
for (i = 0; i < num_filters; i++) {
if (!(mfval & BIT(MFVAL_IPV6_FILTER_SHIFT + i)))
continue;
for (j = 0; j < 4; j++) {
reg = IXGBE_READ_REG(hw, MIPAF_ARR(i, j));
if (reg != xs->id.daddr.a6[j])
break;
}
if (j == 4) /* did we match all 4 words? */
return 1;
}
if ((bmcipval & BMCIP_MASK) == BMCIP_V6) {
for (j = 0; j < 4; j++) {
reg = IXGBE_READ_REG(hw, IXGBE_BMCIP(j));
if (reg != xs->id.daddr.a6[j])
break;
}
if (j == 4) /* did we match all 4 words? */
return 1;
}
}
return 0;
}
/** /**
* ixgbe_ipsec_add_sa - program device with a security association * ixgbe_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct * @xs: pointer to transformer state struct
...@@ -465,6 +548,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs) ...@@ -465,6 +548,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL; return -EINVAL;
} }
if (ixgbe_ipsec_check_mgmt_ip(xs)) {
netdev_err(dev, "IPsec IP addr clash with mgmt filters\n");
return -EINVAL;
}
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa rsa; struct rx_sa rsa;
......
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