diff options
author | Vlad Zolotarov <vladz@cloudius-systems.com> | 2015-03-30 14:35:23 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2015-04-11 00:57:22 -0400 |
commit | 01a3d796813d6302af9f828f34b73d21a4b96c9a (patch) | |
tree | 44165af986242ee8da953ad85da4037a443699e0 | |
parent | 7f276efb45f8b022eeb9a0453240937806dc27e3 (diff) |
if_link: Add an additional parameter to ifla_vf_info for RSS querying
Add configuration setting for drivers to allow/block an RSS Redirection
Table and a Hash Key querying for discrete VFs.
On some devices VF share the mentioned above information with PF and
querying it may adduce a theoretical security risk. We want to let a
system administrator to decide if he/she wants to take this risk or not.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | include/linux/if_link.h | 1 | ||||
-rw-r--r-- | include/linux/netdevice.h | 8 | ||||
-rw-r--r-- | include/uapi/linux/if_link.h | 8 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 32 |
4 files changed, 43 insertions, 6 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 119130e9298b..da4929927f69 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h | |||
@@ -14,5 +14,6 @@ struct ifla_vf_info { | |||
14 | __u32 linkstate; | 14 | __u32 linkstate; |
15 | __u32 min_tx_rate; | 15 | __u32 min_tx_rate; |
16 | __u32 max_tx_rate; | 16 | __u32 max_tx_rate; |
17 | __u32 rss_query_en; | ||
17 | }; | 18 | }; |
18 | #endif /* _LINUX_IF_LINK_H */ | 19 | #endif /* _LINUX_IF_LINK_H */ |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index bf6d9df34d7b..13acb3d8ecdd 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -878,6 +878,11 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, | |||
878 | * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state); | 878 | * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state); |
879 | * int (*ndo_set_vf_port)(struct net_device *dev, int vf, | 879 | * int (*ndo_set_vf_port)(struct net_device *dev, int vf, |
880 | * struct nlattr *port[]); | 880 | * struct nlattr *port[]); |
881 | * | ||
882 | * Enable or disable the VF ability to query its RSS Redirection Table and | ||
883 | * Hash Key. This is needed since on some devices VF share this information | ||
884 | * with PF and querying it may adduce a theoretical security risk. | ||
885 | * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting); | ||
881 | * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); | 886 | * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); |
882 | * int (*ndo_setup_tc)(struct net_device *dev, u8 tc) | 887 | * int (*ndo_setup_tc)(struct net_device *dev, u8 tc) |
883 | * Called to setup 'tc' number of traffic classes in the net device. This | 888 | * Called to setup 'tc' number of traffic classes in the net device. This |
@@ -1099,6 +1104,9 @@ struct net_device_ops { | |||
1099 | struct nlattr *port[]); | 1104 | struct nlattr *port[]); |
1100 | int (*ndo_get_vf_port)(struct net_device *dev, | 1105 | int (*ndo_get_vf_port)(struct net_device *dev, |
1101 | int vf, struct sk_buff *skb); | 1106 | int vf, struct sk_buff *skb); |
1107 | int (*ndo_set_vf_rss_query_en)( | ||
1108 | struct net_device *dev, | ||
1109 | int vf, bool setting); | ||
1102 | int (*ndo_setup_tc)(struct net_device *dev, u8 tc); | 1110 | int (*ndo_setup_tc)(struct net_device *dev, u8 tc); |
1103 | #if IS_ENABLED(CONFIG_FCOE) | 1111 | #if IS_ENABLED(CONFIG_FCOE) |
1104 | int (*ndo_fcoe_enable)(struct net_device *dev); | 1112 | int (*ndo_fcoe_enable)(struct net_device *dev); |
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 7ffb18df01ca..d9cd19214b98 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h | |||
@@ -465,6 +465,9 @@ enum { | |||
465 | IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ | 465 | IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ |
466 | IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ | 466 | IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ |
467 | IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ | 467 | IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ |
468 | IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query | ||
469 | * on/off switch | ||
470 | */ | ||
468 | __IFLA_VF_MAX, | 471 | __IFLA_VF_MAX, |
469 | }; | 472 | }; |
470 | 473 | ||
@@ -509,6 +512,11 @@ struct ifla_vf_link_state { | |||
509 | __u32 link_state; | 512 | __u32 link_state; |
510 | }; | 513 | }; |
511 | 514 | ||
515 | struct ifla_vf_rss_query_en { | ||
516 | __u32 vf; | ||
517 | __u32 setting; | ||
518 | }; | ||
519 | |||
512 | /* VF ports management section | 520 | /* VF ports management section |
513 | * | 521 | * |
514 | * Nested layout of set/get msg is: | 522 | * Nested layout of set/get msg is: |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 7a836152359b..358d52a38533 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -818,7 +818,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
818 | nla_total_size(sizeof(struct ifla_vf_vlan)) + | 818 | nla_total_size(sizeof(struct ifla_vf_vlan)) + |
819 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + | 819 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + |
820 | nla_total_size(sizeof(struct ifla_vf_rate)) + | 820 | nla_total_size(sizeof(struct ifla_vf_rate)) + |
821 | nla_total_size(sizeof(struct ifla_vf_link_state))); | 821 | nla_total_size(sizeof(struct ifla_vf_link_state)) + |
822 | nla_total_size(sizeof(struct ifla_vf_rss_query_en))); | ||
822 | return size; | 823 | return size; |
823 | } else | 824 | } else |
824 | return 0; | 825 | return 0; |
@@ -1132,14 +1133,16 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1132 | struct ifla_vf_tx_rate vf_tx_rate; | 1133 | struct ifla_vf_tx_rate vf_tx_rate; |
1133 | struct ifla_vf_spoofchk vf_spoofchk; | 1134 | struct ifla_vf_spoofchk vf_spoofchk; |
1134 | struct ifla_vf_link_state vf_linkstate; | 1135 | struct ifla_vf_link_state vf_linkstate; |
1136 | struct ifla_vf_rss_query_en vf_rss_query_en; | ||
1135 | 1137 | ||
1136 | /* | 1138 | /* |
1137 | * Not all SR-IOV capable drivers support the | 1139 | * Not all SR-IOV capable drivers support the |
1138 | * spoofcheck query. Preset to -1 so the user | 1140 | * spoofcheck and "RSS query enable" query. Preset to |
1139 | * space tool can detect that the driver didn't | 1141 | * -1 so the user space tool can detect that the driver |
1140 | * report anything. | 1142 | * didn't report anything. |
1141 | */ | 1143 | */ |
1142 | ivi.spoofchk = -1; | 1144 | ivi.spoofchk = -1; |
1145 | ivi.rss_query_en = -1; | ||
1143 | memset(ivi.mac, 0, sizeof(ivi.mac)); | 1146 | memset(ivi.mac, 0, sizeof(ivi.mac)); |
1144 | /* The default value for VF link state is "auto" | 1147 | /* The default value for VF link state is "auto" |
1145 | * IFLA_VF_LINK_STATE_AUTO which equals zero | 1148 | * IFLA_VF_LINK_STATE_AUTO which equals zero |
@@ -1152,7 +1155,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1152 | vf_rate.vf = | 1155 | vf_rate.vf = |
1153 | vf_tx_rate.vf = | 1156 | vf_tx_rate.vf = |
1154 | vf_spoofchk.vf = | 1157 | vf_spoofchk.vf = |
1155 | vf_linkstate.vf = ivi.vf; | 1158 | vf_linkstate.vf = |
1159 | vf_rss_query_en.vf = ivi.vf; | ||
1156 | 1160 | ||
1157 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); | 1161 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); |
1158 | vf_vlan.vlan = ivi.vlan; | 1162 | vf_vlan.vlan = ivi.vlan; |
@@ -1162,6 +1166,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1162 | vf_rate.max_tx_rate = ivi.max_tx_rate; | 1166 | vf_rate.max_tx_rate = ivi.max_tx_rate; |
1163 | vf_spoofchk.setting = ivi.spoofchk; | 1167 | vf_spoofchk.setting = ivi.spoofchk; |
1164 | vf_linkstate.link_state = ivi.linkstate; | 1168 | vf_linkstate.link_state = ivi.linkstate; |
1169 | vf_rss_query_en.setting = ivi.rss_query_en; | ||
1165 | vf = nla_nest_start(skb, IFLA_VF_INFO); | 1170 | vf = nla_nest_start(skb, IFLA_VF_INFO); |
1166 | if (!vf) { | 1171 | if (!vf) { |
1167 | nla_nest_cancel(skb, vfinfo); | 1172 | nla_nest_cancel(skb, vfinfo); |
@@ -1176,7 +1181,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1176 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), | 1181 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), |
1177 | &vf_spoofchk) || | 1182 | &vf_spoofchk) || |
1178 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), | 1183 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), |
1179 | &vf_linkstate)) | 1184 | &vf_linkstate) || |
1185 | nla_put(skb, IFLA_VF_RSS_QUERY_EN, | ||
1186 | sizeof(vf_rss_query_en), | ||
1187 | &vf_rss_query_en)) | ||
1180 | goto nla_put_failure; | 1188 | goto nla_put_failure; |
1181 | nla_nest_end(skb, vf); | 1189 | nla_nest_end(skb, vf); |
1182 | } | 1190 | } |
@@ -1290,6 +1298,7 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { | |||
1290 | [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, | 1298 | [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, |
1291 | [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, | 1299 | [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, |
1292 | [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, | 1300 | [IFLA_VF_LINK_STATE] = { .len = sizeof(struct ifla_vf_link_state) }, |
1301 | [IFLA_VF_RSS_QUERY_EN] = { .len = sizeof(struct ifla_vf_rss_query_en) }, | ||
1293 | }; | 1302 | }; |
1294 | 1303 | ||
1295 | static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { | 1304 | static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = { |
@@ -1500,6 +1509,17 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) | |||
1500 | ivl->link_state); | 1509 | ivl->link_state); |
1501 | break; | 1510 | break; |
1502 | } | 1511 | } |
1512 | case IFLA_VF_RSS_QUERY_EN: { | ||
1513 | struct ifla_vf_rss_query_en *ivrssq_en; | ||
1514 | |||
1515 | ivrssq_en = nla_data(vf); | ||
1516 | err = -EOPNOTSUPP; | ||
1517 | if (ops->ndo_set_vf_rss_query_en) | ||
1518 | err = ops->ndo_set_vf_rss_query_en(dev, | ||
1519 | ivrssq_en->vf, | ||
1520 | ivrssq_en->setting); | ||
1521 | break; | ||
1522 | } | ||
1503 | default: | 1523 | default: |
1504 | err = -EINVAL; | 1524 | err = -EINVAL; |
1505 | break; | 1525 | break; |