i40e: implement anti-spoofing for VFs
authorMitch Williams <mitch.a.williams@intel.com>
Tue, 20 May 2014 08:01:40 +0000 (08:01 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 9 Jun 2014 06:52:33 +0000 (23:52 -0700)
Our hardware supports VF antispoofing for both MAC addresses and VLANs.
Enable this feature by default for all VFs and implement the netdev op
to control it from the command line.

Change-ID: Ifb941da22785848aa3aba6b2231be135b8ea8f31
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h

index d0bc05f224ff8c4f553101aed0d0bce787be42cd..afc37d3b210151b7784b938cc51d81f3789d815b 100644 (file)
@@ -6887,6 +6887,7 @@ static const struct net_device_ops i40e_netdev_ops = {
        .ndo_set_vf_rate        = i40e_ndo_set_vf_bw,
        .ndo_get_vf_config      = i40e_ndo_get_vf_config,
        .ndo_set_vf_link_state  = i40e_ndo_set_vf_link_state,
+       .ndo_set_vf_spoofchk    = i40e_ndo_set_vf_spoofck,
 #ifdef CONFIG_I40E_VXLAN
        .ndo_add_vxlan_port     = i40e_add_vxlan_port,
        .ndo_del_vxlan_port     = i40e_del_vxlan_port,
@@ -7121,6 +7122,13 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
 
                ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
                ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
+               if (pf->vf[vsi->vf_id].spoofchk) {
+                       ctxt.info.valid_sections |=
+                               cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+                       ctxt.info.sec_flags |=
+                               (I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK |
+                                I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK);
+               }
                /* Setup the VSI tx/rx queue map for TC0 only for now */
                i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true);
                break;
index 4e7634c83685adc38f14ad4168657f6128ae849c..3f6cad46365c636fc54eb4b8357e4f53daf87013 100644 (file)
@@ -899,6 +899,7 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
                ret = -ENOMEM;
                goto err_alloc;
        }
+       pf->vf = vfs;
 
        /* apply default profile */
        for (i = 0; i < num_alloc_vfs; i++) {
@@ -908,13 +909,13 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
 
                /* assign default capabilities */
                set_bit(I40E_VIRTCHNL_VF_CAP_L2, &vfs[i].vf_caps);
+               vfs[i].spoofchk = true;
                /* vf resources get allocated during reset */
                i40e_reset_vf(&vfs[i], false);
 
                /* enable vf vplan_qtable mappings */
                i40e_enable_vf_mappings(&vfs[i]);
        }
-       pf->vf = vfs;
        pf->num_alloc_vfs = num_alloc_vfs;
 
        i40e_enable_pf_switch_lb(pf);
@@ -2328,7 +2329,7 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
                ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE;
        else
                ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE;
-
+       ivi->spoofchk = vf->spoofchk;
        ret = 0;
 
 error_param:
@@ -2395,3 +2396,50 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
 error_out:
        return ret;
 }
+
+/**
+ * i40e_ndo_set_vf_spoofchk
+ * @netdev: network interface device structure
+ * @vf_id: vf identifier
+ * @enable: flag to enable or disable feature
+ *
+ * Enable or disable VF spoof checking
+ **/
+int i40e_ndo_set_vf_spoofck(struct net_device *netdev, int vf_id, bool enable)
+{
+       struct i40e_netdev_priv *np = netdev_priv(netdev);
+       struct i40e_vsi *vsi = np->vsi;
+       struct i40e_pf *pf = vsi->back;
+       struct i40e_vsi_context ctxt;
+       struct i40e_hw *hw = &pf->hw;
+       struct i40e_vf *vf;
+       int ret = 0;
+
+       /* validate the request */
+       if (vf_id >= pf->num_alloc_vfs) {
+               dev_err(&pf->pdev->dev, "Invalid VF Identifier %d\n", vf_id);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       vf = &(pf->vf[vf_id]);
+
+       if (enable == vf->spoofchk)
+               goto out;
+
+       vf->spoofchk = enable;
+       memset(&ctxt, 0, sizeof(ctxt));
+       ctxt.seid = pf->vsi[vf->lan_vsi_index]->seid;
+       ctxt.pf_num = pf->hw.pf_id;
+       ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+       if (enable)
+               ctxt.info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
+       ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+       if (ret) {
+               dev_err(&pf->pdev->dev, "Error %d updating VSI parameters\n",
+                       ret);
+               ret = -EIO;
+       }
+out:
+       return ret;
+}
index 5a559be4ba2ca926b92fc65dbbb1fb5ca0f727cf..63e7e0d81ad22754622695dabc1a0475885477ee 100644 (file)
@@ -101,6 +101,7 @@ struct i40e_vf {
        unsigned int tx_rate;   /* Tx bandwidth limit in Mbps */
        bool link_forced;
        bool link_up;           /* only valid if vf link is forced */
+       bool spoofchk;
 };
 
 void i40e_free_vfs(struct i40e_pf *pf);
@@ -121,6 +122,7 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
 int i40e_ndo_get_vf_config(struct net_device *netdev,
                           int vf_id, struct ifla_vf_info *ivi);
 int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link);
+int i40e_ndo_set_vf_spoofck(struct net_device *netdev, int vf_id, bool enable);
 
 void i40e_vc_notify_link_state(struct i40e_pf *pf);
 void i40e_vc_notify_reset(struct i40e_pf *pf);