Skip to content

Commit bf79586

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2015-10-23 This series contains updates to i40e, i40evf, if_link, ixgbe and ixgbevf. Anjali adds a workaround to drop any flow control frames from being transmitted from any VSI, so that a malicious VF cannot send flow control or PFC packets out on the wire. Also fixed a bug in debugfs by grabbing the filter list lock before adding or deleting a filter. Akeem fixes an issue where we were unconditionally returning VEB bridge mode before allowing LB in the add VSI routine, resolve by checking if the bridge is actually in VEB mode first. Mitch fixed an issue where the incorrect structure was being used for VLAN filter list, which meant the VLAN filter list did not get processed correctly and VLAN filters would not be re-enabled after any kind of reset. Helin fixed a problem of possibly getting inconsistent flow control status after a PF reset. The issue was requested_mode was being set with a default value during probe, but the hardware state could be a different value from this mode. Carolyn fixed a problem where the driver output of the OEM version string varied from the other tools. Jean Sacren fixes up kernel documentation by fixing function header comments to match actual variables used in the functions. Also cleaned up variable initialization, when the variable would be over-written immediately. Hiroshi Shimanoto provides three patches to add "trusted" VF by adding netlink directives and an NDO entry. Then implement these new controls in ixgbe and ixgbevf. This series has gone through several iterations to address all the suggested community changes and concerns. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e74f510 + 8443c1a commit bf79586

25 files changed

+318
-59
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@
109109
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
110110
#define I40E_NVM_VERSION_HI_SHIFT 12
111111
#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT)
112-
#define I40E_OEM_VER_BUILD_MASK 0xff00
112+
#define I40E_OEM_VER_BUILD_MASK 0xffff
113113
#define I40E_OEM_VER_PATCH_MASK 0xff
114+
#define I40E_OEM_VER_BUILD_SHIFT 8
115+
#define I40E_OEM_VER_SHIFT 24
114116

115117
/* The values in here are decimal coded as hex as is the case in the NVM map*/
116118
#define I40E_CURRENT_NVM_VERSION_HI 0x2
@@ -594,16 +596,23 @@ struct i40e_device {
594596
static inline char *i40e_nvm_version_str(struct i40e_hw *hw)
595597
{
596598
static char buf[32];
599+
u32 full_ver;
600+
u8 ver, patch;
601+
u16 build;
602+
603+
full_ver = hw->nvm.oem_ver;
604+
ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT);
605+
build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT)
606+
& I40E_OEM_VER_BUILD_MASK);
607+
patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK);
597608

598609
snprintf(buf, sizeof(buf),
599610
"%x.%02x 0x%x %d.%d.%d",
600611
(hw->nvm.version & I40E_NVM_VERSION_HI_MASK) >>
601612
I40E_NVM_VERSION_HI_SHIFT,
602613
(hw->nvm.version & I40E_NVM_VERSION_LO_MASK) >>
603614
I40E_NVM_VERSION_LO_SHIFT,
604-
hw->nvm.eetrack, (hw->nvm.oem_ver >> 24),
605-
(hw->nvm.oem_ver & I40E_OEM_VER_BUILD_MASK) >> 8,
606-
hw->nvm.oem_ver & I40E_OEM_VER_PATCH_MASK);
615+
hw->nvm.eetrack, ver, build, patch);
607616

608617
return buf;
609618
}

drivers/net/ethernet/intel/i40e/i40e_common.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,25 +331,11 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
331331
len = buf_len;
332332
/* write the full 16-byte chunks */
333333
for (i = 0; i < (len - 16); i += 16)
334-
i40e_debug(hw, mask,
335-
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
336-
i, buf[i], buf[i + 1], buf[i + 2],
337-
buf[i + 3], buf[i + 4], buf[i + 5],
338-
buf[i + 6], buf[i + 7], buf[i + 8],
339-
buf[i + 9], buf[i + 10], buf[i + 11],
340-
buf[i + 12], buf[i + 13], buf[i + 14],
341-
buf[i + 15]);
334+
i40e_debug(hw, mask, "\t0x%04X %16ph\n", i, buf + i);
342335
/* write whatever's left over without overrunning the buffer */
343-
if (i < len) {
344-
char d_buf[80];
345-
int j = 0;
346-
347-
memset(d_buf, 0, sizeof(d_buf));
348-
j += sprintf(d_buf, "\t0x%04X ", i);
349-
while (i < len)
350-
j += sprintf(&d_buf[j], " %02X", buf[i++]);
351-
i40e_debug(hw, mask, "%s\n", d_buf);
352-
}
336+
if (i < len)
337+
i40e_debug(hw, mask, "\t0x%04X %*ph\n",
338+
i, len - i, buf + i);
353339
}
354340
}
355341

@@ -3828,6 +3814,28 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
38283814
return status;
38293815
}
38303816

3817+
/**
3818+
* i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
3819+
* @hw: pointer to the hw struct
3820+
* @seid: VSI seid to add ethertype filter from
3821+
**/
3822+
#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
3823+
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
3824+
u16 seid)
3825+
{
3826+
u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
3827+
I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
3828+
I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
3829+
u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
3830+
i40e_status status;
3831+
3832+
status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
3833+
seid, 0, true, NULL,
3834+
NULL);
3835+
if (status)
3836+
hw_dbg(hw, "Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
3837+
}
3838+
38313839
/**
38323840
* i40e_aq_alternate_read
38333841
* @hw: pointer to the hardware structure

drivers/net/ethernet/intel/i40e/i40e_debugfs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
11371137
goto command_write_done;
11381138
}
11391139

1140+
spin_lock_bh(&vsi->mac_filter_list_lock);
11401141
f = i40e_add_filter(vsi, ma, vlan, false, false);
1142+
spin_unlock_bh(&vsi->mac_filter_list_lock);
11411143
ret = i40e_sync_vsi_filters(vsi, true);
11421144
if (f && !ret)
11431145
dev_info(&pf->pdev->dev,
@@ -1174,7 +1176,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
11741176
goto command_write_done;
11751177
}
11761178

1179+
spin_lock_bh(&vsi->mac_filter_list_lock);
11771180
i40e_del_filter(vsi, ma, vlan, false, false);
1181+
spin_unlock_bh(&vsi->mac_filter_list_lock);
11781182
ret = i40e_sync_vsi_filters(vsi, true);
11791183
if (!ret)
11801184
dev_info(&pf->pdev->dev,

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
3939

4040
#define DRV_VERSION_MAJOR 1
4141
#define DRV_VERSION_MINOR 3
42-
#define DRV_VERSION_BUILD 38
42+
#define DRV_VERSION_BUILD 46
4343
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
4444
__stringify(DRV_VERSION_MINOR) "." \
4545
__stringify(DRV_VERSION_BUILD) DRV_KERN
@@ -6837,6 +6837,15 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
68376837
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
68386838
ret = i40e_setup_misc_vector(pf);
68396839

6840+
/* Add a filter to drop all Flow control frames from any VSI from being
6841+
* transmitted. By doing so we stop a malicious VF from sending out
6842+
* PAUSE or PFC frames and potentially controlling traffic for other
6843+
* PF/VF VSIs.
6844+
* The FW can still send Flow control frames if enabled.
6845+
*/
6846+
i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
6847+
pf->main_vsi_seid);
6848+
68406849
/* restart the VSIs that were rebuilt and running before the reset */
68416850
i40e_pf_unquiesce_all_vsi(pf);
68426851

@@ -8732,12 +8741,22 @@ int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi)
87328741
return 1;
87338742

87348743
veb = pf->veb[vsi->veb_idx];
8744+
if (!veb) {
8745+
dev_info(&pf->pdev->dev,
8746+
"There is no veb associated with the bridge\n");
8747+
return -ENOENT;
8748+
}
8749+
87358750
/* Uplink is a bridge in VEPA mode */
8736-
if (veb && (veb->bridge_mode & BRIDGE_MODE_VEPA))
8751+
if (veb->bridge_mode & BRIDGE_MODE_VEPA) {
87378752
return 0;
8753+
} else {
8754+
/* Uplink is a bridge in VEB mode */
8755+
return 1;
8756+
}
87388757

8739-
/* Uplink is a bridge in VEB mode */
8740-
return 1;
8758+
/* VEPA is now default bridge, so return 0 */
8759+
return 0;
87418760
}
87428761

87438762
/**
@@ -10164,6 +10183,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1016410183
int err;
1016510184
u32 len;
1016610185
u32 i;
10186+
u8 set_fc_aq_fail;
1016710187

1016810188
err = pci_enable_device_mem(pdev);
1016910189
if (err)
@@ -10428,6 +10448,25 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1042810448
dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
1042910449
goto err_vsis;
1043010450
}
10451+
10452+
/* Make sure flow control is set according to current settings */
10453+
err = i40e_set_fc(hw, &set_fc_aq_fail, true);
10454+
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_GET)
10455+
dev_dbg(&pf->pdev->dev,
10456+
"Set fc with err %s aq_err %s on get_phy_cap\n",
10457+
i40e_stat_str(hw, err),
10458+
i40e_aq_str(hw, hw->aq.asq_last_status));
10459+
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_SET)
10460+
dev_dbg(&pf->pdev->dev,
10461+
"Set fc with err %s aq_err %s on set_phy_config\n",
10462+
i40e_stat_str(hw, err),
10463+
i40e_aq_str(hw, hw->aq.asq_last_status));
10464+
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_UPDATE)
10465+
dev_dbg(&pf->pdev->dev,
10466+
"Set fc with err %s aq_err %s on get_link_info\n",
10467+
i40e_stat_str(hw, err),
10468+
i40e_aq_str(hw, hw->aq.asq_last_status));
10469+
1043110470
/* if FDIR VSI was set up, start it now */
1043210471
for (i = 0; i < pf->num_alloc_vsi; i++) {
1043310472
if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) {
@@ -10585,6 +10624,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1058510624
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
1058610625
pf->hw.phy.phy_types = le32_to_cpu(abilities.phy_type);
1058710626

10627+
/* Add a filter to drop all Flow control frames from any VSI from being
10628+
* transmitted. By doing so we stop a malicious VF from sending out
10629+
* PAUSE or PFC frames and potentially controlling traffic for other
10630+
* PF/VF VSIs.
10631+
* The FW can still send Flow control frames if enabled.
10632+
*/
10633+
i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
10634+
pf->main_vsi_seid);
10635+
1058810636
/* print a string summarizing features */
1058910637
i40e_print_features(pf);
1059010638

drivers/net/ethernet/intel/i40e/i40e_nvm.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
484484
static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
485485
u16 *checksum)
486486
{
487-
i40e_status ret_code = 0;
487+
i40e_status ret_code;
488488
struct i40e_virt_mem vmem;
489489
u16 pcie_alt_module = 0;
490490
u16 checksum_local = 0;
@@ -564,15 +564,16 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
564564
**/
565565
i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
566566
{
567-
i40e_status ret_code = 0;
567+
i40e_status ret_code;
568568
u16 checksum;
569569
__le16 le_sum;
570570

571571
ret_code = i40e_calc_nvm_checksum(hw, &checksum);
572-
le_sum = cpu_to_le16(checksum);
573-
if (!ret_code)
572+
if (!ret_code) {
573+
le_sum = cpu_to_le16(checksum);
574574
ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
575575
1, &le_sum, true);
576+
}
576577

577578
return ret_code;
578579
}

drivers/net/ethernet/intel/i40e/i40e_prototype.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,6 @@ i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
322322
void *buff, u16 *ret_buff_size,
323323
u8 *ret_next_table, u32 *ret_next_index,
324324
struct i40e_asq_cmd_details *cmd_details);
325+
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
326+
u16 vsi_seid);
325327
#endif /* _I40E_PROTOTYPE_H_ */

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
21872187
* @tx_ring: ptr to the ring to send
21882188
* @skb: ptr to the skb we're sending
21892189
* @hdr_len: ptr to the size of the packet header
2190+
* @cd_type_cmd_tso_mss: ptr to u64 object
21902191
* @cd_tunneling: ptr to context descriptor bits
21912192
*
21922193
* Returns 0 if no TSO can happen, 1 if tso is going, or error
@@ -2246,6 +2247,7 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
22462247
* @tx_ring: ptr to the ring to send
22472248
* @skb: ptr to the skb we're sending
22482249
* @tx_flags: the collected send information
2250+
* @cd_type_cmd_tso_mss: ptr to u64 object
22492251
*
22502252
* Returns 0 if no Tx timestamp can happen and 1 if the timestamp will happen
22512253
**/
@@ -2288,6 +2290,7 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
22882290
* @tx_flags: pointer to Tx flags currently set
22892291
* @td_cmd: Tx descriptor command bits to set
22902292
* @td_offset: Tx descriptor header offsets to set
2293+
* @tx_ring: Tx descriptor ring
22912294
* @cd_tunneling: ptr to context desc bits
22922295
**/
22932296
static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
944944
if (pci_num_vf(pf->pdev) != num_alloc_vfs) {
945945
ret = pci_enable_sriov(pf->pdev, num_alloc_vfs);
946946
if (ret) {
947+
pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED;
947948
pf->num_alloc_vfs = 0;
948949
goto err_iov;
949950
}

drivers/net/ethernet/intel/i40evf/i40e_common.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,25 +331,11 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
331331
len = buf_len;
332332
/* write the full 16-byte chunks */
333333
for (i = 0; i < (len - 16); i += 16)
334-
i40e_debug(hw, mask,
335-
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
336-
i, buf[i], buf[i + 1], buf[i + 2],
337-
buf[i + 3], buf[i + 4], buf[i + 5],
338-
buf[i + 6], buf[i + 7], buf[i + 8],
339-
buf[i + 9], buf[i + 10], buf[i + 11],
340-
buf[i + 12], buf[i + 13], buf[i + 14],
341-
buf[i + 15]);
334+
i40e_debug(hw, mask, "\t0x%04X %16ph\n", i, buf + i);
342335
/* write whatever's left over without overrunning the buffer */
343-
if (i < len) {
344-
char d_buf[80];
345-
int j = 0;
346-
347-
memset(d_buf, 0, sizeof(d_buf));
348-
j += sprintf(d_buf, "\t0x%04X ", i);
349-
while (i < len)
350-
j += sprintf(&d_buf[j], " %02X", buf[i++]);
351-
i40e_debug(hw, mask, "%s\n", d_buf);
352-
}
336+
if (i < len)
337+
i40e_debug(hw, mask, "\t0x%04X %*ph\n",
338+
i, len - i, buf + i);
353339
}
354340
}
355341

drivers/net/ethernet/intel/i40evf/i40e_prototype.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,6 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
101101
u16 vsi_seid, u16 queue, bool is_add,
102102
struct i40e_control_filter_stats *stats,
103103
struct i40e_asq_cmd_details *cmd_details);
104+
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
105+
u16 vsi_seid);
104106
#endif /* _I40E_PROTOTYPE_H_ */

drivers/net/ethernet/intel/i40evf/i40evf_main.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ char i40evf_driver_name[] = "i40evf";
3434
static const char i40evf_driver_string[] =
3535
"Intel(R) XL710/X710 Virtual Function Network Driver";
3636

37-
#define DRV_VERSION "1.3.25"
37+
#define DRV_VERSION "1.3.33"
3838
const char i40evf_driver_version[] = DRV_VERSION;
3939
static const char i40evf_copyright[] =
4040
"Copyright (c) 2013 - 2015 Intel Corporation.";
@@ -282,6 +282,7 @@ static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, u32 mask)
282282
/**
283283
* i40evf_irq_enable - Enable default interrupt generation settings
284284
* @adapter: board private structure
285+
* @flush: boolean value whether to run rd32()
285286
**/
286287
void i40evf_irq_enable(struct i40evf_adapter *adapter, bool flush)
287288
{
@@ -305,15 +306,14 @@ static irqreturn_t i40evf_msix_aq(int irq, void *data)
305306
struct i40evf_adapter *adapter = netdev_priv(netdev);
306307
struct i40e_hw *hw = &adapter->hw;
307308
u32 val;
308-
u32 ena_mask;
309309

310310
/* handle non-queue interrupts */
311-
val = rd32(hw, I40E_VFINT_ICR01);
312-
ena_mask = rd32(hw, I40E_VFINT_ICR0_ENA1);
311+
rd32(hw, I40E_VFINT_ICR01);
312+
rd32(hw, I40E_VFINT_ICR0_ENA1);
313313

314314

315-
val = rd32(hw, I40E_VFINT_DYN_CTL01);
316-
val = val | I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
315+
val = rd32(hw, I40E_VFINT_DYN_CTL01) |
316+
I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
317317
wr32(hw, I40E_VFINT_DYN_CTL01, val);
318318

319319
/* schedule work on the private workqueue */
@@ -1609,6 +1609,7 @@ static void i40evf_reset_task(struct work_struct *work)
16091609
reset_task);
16101610
struct net_device *netdev = adapter->netdev;
16111611
struct i40e_hw *hw = &adapter->hw;
1612+
struct i40evf_vlan_filter *vlf;
16121613
struct i40evf_mac_filter *f;
16131614
u32 reg_val;
16141615
int i = 0, err;
@@ -1732,8 +1733,8 @@ static void i40evf_reset_task(struct work_struct *work)
17321733
f->add = true;
17331734
}
17341735
/* re-add all VLAN filters */
1735-
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
1736-
f->add = true;
1736+
list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
1737+
vlf->add = true;
17371738
}
17381739
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
17391740
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,17 @@ struct vf_data_storage {
152152
u16 vlan_count;
153153
u8 spoofchk_enabled;
154154
bool rss_query_enabled;
155+
u8 trusted;
156+
int xcast_mode;
155157
unsigned int vf_api;
156158
};
157159

160+
enum ixgbevf_xcast_modes {
161+
IXGBEVF_XCAST_MODE_NONE = 0,
162+
IXGBEVF_XCAST_MODE_MULTI,
163+
IXGBEVF_XCAST_MODE_ALLMULTI,
164+
};
165+
158166
struct vf_macvlans {
159167
struct list_head l;
160168
int vf;

0 commit comments

Comments
 (0)