if_link: Add control trust VF
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Fri, 28 Aug 2015 06:57:55 +0000 (06:57 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 23 Oct 2015 12:44:28 +0000 (05:44 -0700)
Add netlink directives and ndo entry to trust VF user.

This controls the special permission of VF user.
The administrator will dedicatedly trust VF user to use some features
which impacts security and/or performance.

The administrator never turn it on unless VF user is fully trusted.

CC: Sy Jong Choi <sy.jong.choi@intel.com>
Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
include/linux/if_link.h
include/linux/netdevice.h
include/uapi/linux/if_link.h
net/core/rtnetlink.c

index ae5d0d22955d8fdedba5b03d981dbcdd7585ee03..f923d15b432c75b831a57eb9d2f1f532684eb689 100644 (file)
@@ -24,5 +24,6 @@ struct ifla_vf_info {
        __u32 min_tx_rate;
        __u32 max_tx_rate;
        __u32 rss_query_en;
+       __u32 trusted;
 };
 #endif /* _LINUX_IF_LINK_H */
index 69fdd427c8cb8ff5f54c01c16481d0d39258c6de..773383859bd90eb576d76c61963d0b6f7a78be54 100644 (file)
@@ -881,6 +881,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
  * int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate,
  *                       int max_tx_rate);
  * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
+ * int (*ndo_set_vf_trust)(struct net_device *dev, int vf, bool setting);
  * int (*ndo_get_vf_config)(struct net_device *dev,
  *                         int vf, struct ifla_vf_info *ivf);
  * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);
@@ -1109,6 +1110,8 @@ struct net_device_ops {
                                                   int max_tx_rate);
        int                     (*ndo_set_vf_spoofchk)(struct net_device *dev,
                                                       int vf, bool setting);
+       int                     (*ndo_set_vf_trust)(struct net_device *dev,
+                                                   int vf, bool setting);
        int                     (*ndo_get_vf_config)(struct net_device *dev,
                                                     int vf,
                                                     struct ifla_vf_info *ivf);
index e3b6217f34f1138644bc6d2ffc20448d68301a89..a7aea8418abbbc3ff46c39f9d1b955c3814cc5ce 100644 (file)
@@ -550,6 +550,7 @@ enum {
                                 * on/off switch
                                 */
        IFLA_VF_STATS,          /* network device statistics */
+       IFLA_VF_TRUST,          /* Trust VF */
        __IFLA_VF_MAX,
 };
 
@@ -611,6 +612,11 @@ enum {
 
 #define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
 
+struct ifla_vf_trust {
+       __u32 vf;
+       __u32 setting;
+};
+
 /* VF ports management section
  *
  *     Nested layout of set/get msg is:
index 7c78b5aca944d56eb063716aec41944f862cdc02..504bd17b7456c3a16a0832ed28ede040c41ff316 100644 (file)
@@ -838,7 +838,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
                         /* IFLA_VF_STATS_BROADCAST */
                         nla_total_size(sizeof(__u64)) +
                         /* IFLA_VF_STATS_MULTICAST */
-                        nla_total_size(sizeof(__u64)));
+                        nla_total_size(sizeof(__u64)) +
+                        nla_total_size(sizeof(struct ifla_vf_trust)));
                return size;
        } else
                return 0;
@@ -1161,6 +1162,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                        struct ifla_vf_link_state vf_linkstate;
                        struct ifla_vf_rss_query_en vf_rss_query_en;
                        struct ifla_vf_stats vf_stats;
+                       struct ifla_vf_trust vf_trust;
 
                        /*
                         * Not all SR-IOV capable drivers support the
@@ -1170,6 +1172,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                         */
                        ivi.spoofchk = -1;
                        ivi.rss_query_en = -1;
+                       ivi.trusted = -1;
                        memset(ivi.mac, 0, sizeof(ivi.mac));
                        /* The default value for VF link state is "auto"
                         * IFLA_VF_LINK_STATE_AUTO which equals zero
@@ -1183,7 +1186,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                                vf_tx_rate.vf =
                                vf_spoofchk.vf =
                                vf_linkstate.vf =
-                               vf_rss_query_en.vf = ivi.vf;
+                               vf_rss_query_en.vf =
+                               vf_trust.vf = ivi.vf;
 
                        memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
                        vf_vlan.vlan = ivi.vlan;
@@ -1194,6 +1198,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                        vf_spoofchk.setting = ivi.spoofchk;
                        vf_linkstate.link_state = ivi.linkstate;
                        vf_rss_query_en.setting = ivi.rss_query_en;
+                       vf_trust.setting = ivi.trusted;
                        vf = nla_nest_start(skb, IFLA_VF_INFO);
                        if (!vf) {
                                nla_nest_cancel(skb, vfinfo);
@@ -1211,7 +1216,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                                    &vf_linkstate) ||
                            nla_put(skb, IFLA_VF_RSS_QUERY_EN,
                                    sizeof(vf_rss_query_en),
-                                   &vf_rss_query_en))
+                                   &vf_rss_query_en) ||
+                           nla_put(skb, IFLA_VF_TRUST,
+                                   sizeof(vf_trust), &vf_trust))
                                goto nla_put_failure;
                        memset(&vf_stats, 0, sizeof(vf_stats));
                        if (dev->netdev_ops->ndo_get_vf_stats)
@@ -1348,6 +1355,7 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
        [IFLA_VF_LINK_STATE]    = { .len = sizeof(struct ifla_vf_link_state) },
        [IFLA_VF_RSS_QUERY_EN]  = { .len = sizeof(struct ifla_vf_rss_query_en) },
        [IFLA_VF_STATS]         = { .type = NLA_NESTED },
+       [IFLA_VF_TRUST]         = { .len = sizeof(struct ifla_vf_trust) },
 };
 
 static const struct nla_policy ifla_vf_stats_policy[IFLA_VF_STATS_MAX + 1] = {
@@ -1587,6 +1595,16 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
                        return err;
        }
 
+       if (tb[IFLA_VF_TRUST]) {
+               struct ifla_vf_trust *ivt = nla_data(tb[IFLA_VF_TRUST]);
+
+               err = -EOPNOTSUPP;
+               if (ops->ndo_set_vf_trust)
+                       err = ops->ndo_set_vf_trust(dev, ivt->vf, ivt->setting);
+               if (err < 0)
+                       return err;
+       }
+
        return err;
 }