[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180604175644.24293-12-jeffrey.t.kirsher@intel.com>
Date: Mon, 4 Jun 2018 10:56:43 -0700
From: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
To: davem@...emloft.net
Cc: Shannon Nelson <shannon.nelson@...cle.com>, netdev@...r.kernel.org,
nhorman@...hat.com, sassmann@...hat.com, jogreene@...hat.com,
Jeff Kirsher <jeffrey.t.kirsher@...el.com>
Subject: [net-next 11/12] ixgbe: check ipsec ip addr against mgmt filters
From: Shannon Nelson <shannon.nelson@...cle.com>
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: Jesse Brandeburg <jesse.brandeburg@...el.com>
Signed-off-by: Shannon Nelson <shannon.nelson@...cle.com>
Tested-by: Andrew Bowers <andrewx.bowers@...el.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
---
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 88 +++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 99b170f1efd1..e1c976271bbd 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -444,6 +444,89 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
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
* @xs: pointer to transformer state struct
@@ -465,6 +548,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
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) {
struct rx_sa rsa;
--
2.17.1
Powered by blists - more mailing lists