1
1
// SPDX-License-Identifier: GPL-2.0
2
2
/*
3
- * Copyright (C) 2017 - Cambridge Greys Limited
3
+ * Copyright (C) 2017 - 2019 Cambridge Greys Limited
4
4
* Copyright (C) 2011 - 2014 Cisco Systems Inc
5
5
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
6
6
* Copyright (C) 2001 Lennert Buytenhek ([email protected] ) and
21
21
#include <linux/skbuff.h>
22
22
#include <linux/slab.h>
23
23
#include <linux/interrupt.h>
24
+ #include <linux/firmware.h>
25
+ #include <linux/fs.h>
26
+ #include <uapi/linux/filter.h>
24
27
#include <init.h>
25
28
#include <irq_kern.h>
26
29
#include <irq_user.h>
@@ -128,6 +131,23 @@ static int get_mtu(struct arglist *def)
128
131
return ETH_MAX_PACKET ;
129
132
}
130
133
134
+ static char * get_bpf_file (struct arglist * def )
135
+ {
136
+ return uml_vector_fetch_arg (def , "bpffile" );
137
+ }
138
+
139
+ static bool get_bpf_flash (struct arglist * def )
140
+ {
141
+ char * allow = uml_vector_fetch_arg (def , "bpfflash" );
142
+ long result ;
143
+
144
+ if (allow != NULL ) {
145
+ if (kstrtoul (allow , 10 , & result ) == 0 )
146
+ return (allow > 0 );
147
+ }
148
+ return false;
149
+ }
150
+
131
151
static int get_depth (struct arglist * def )
132
152
{
133
153
char * mtu = uml_vector_fetch_arg (def , "depth" );
@@ -176,6 +196,7 @@ static int get_transport_options(struct arglist *def)
176
196
int vec_rx = VECTOR_RX ;
177
197
int vec_tx = VECTOR_TX ;
178
198
long parsed ;
199
+ int result = 0 ;
179
200
180
201
if (vector != NULL ) {
181
202
if (kstrtoul (vector , 10 , & parsed ) == 0 ) {
@@ -186,14 +207,16 @@ static int get_transport_options(struct arglist *def)
186
207
}
187
208
}
188
209
210
+ if (get_bpf_flash (def ))
211
+ result = VECTOR_BPF_FLASH ;
189
212
190
213
if (strncmp (transport , TRANS_TAP , TRANS_TAP_LEN ) == 0 )
191
- return 0 ;
214
+ return result ;
192
215
if (strncmp (transport , TRANS_HYBRID , TRANS_HYBRID_LEN ) == 0 )
193
- return (vec_rx | VECTOR_BPF );
216
+ return (result | vec_rx | VECTOR_BPF );
194
217
if (strncmp (transport , TRANS_RAW , TRANS_RAW_LEN ) == 0 )
195
- return (vec_rx | vec_tx | VECTOR_QDISC_BYPASS );
196
- return (vec_rx | vec_tx );
218
+ return (result | vec_rx | vec_tx | VECTOR_QDISC_BYPASS );
219
+ return (result | vec_rx | vec_tx );
197
220
}
198
221
199
222
@@ -1139,14 +1162,19 @@ static int vector_net_close(struct net_device *dev)
1139
1162
}
1140
1163
tasklet_kill (& vp -> tx_poll );
1141
1164
if (vp -> fds -> rx_fd > 0 ) {
1165
+ if (vp -> bpf )
1166
+ uml_vector_detach_bpf (vp -> fds -> rx_fd , vp -> bpf );
1142
1167
os_close_file (vp -> fds -> rx_fd );
1143
1168
vp -> fds -> rx_fd = -1 ;
1144
1169
}
1145
1170
if (vp -> fds -> tx_fd > 0 ) {
1146
1171
os_close_file (vp -> fds -> tx_fd );
1147
1172
vp -> fds -> tx_fd = -1 ;
1148
1173
}
1174
+ if (vp -> bpf != NULL )
1175
+ kfree (vp -> bpf -> filter );
1149
1176
kfree (vp -> bpf );
1177
+ vp -> bpf = NULL ;
1150
1178
kfree (vp -> fds -> remote_addr );
1151
1179
kfree (vp -> transport_data );
1152
1180
kfree (vp -> header_rxbuffer );
@@ -1181,6 +1209,7 @@ static void vector_reset_tx(struct work_struct *work)
1181
1209
netif_start_queue (vp -> dev );
1182
1210
netif_wake_queue (vp -> dev );
1183
1211
}
1212
+
1184
1213
static int vector_net_open (struct net_device * dev )
1185
1214
{
1186
1215
struct vector_private * vp = netdev_priv (dev );
@@ -1196,6 +1225,8 @@ static int vector_net_open(struct net_device *dev)
1196
1225
vp -> opened = true;
1197
1226
spin_unlock_irqrestore (& vp -> lock , flags );
1198
1227
1228
+ vp -> bpf = uml_vector_user_bpf (get_bpf_file (vp -> parsed ));
1229
+
1199
1230
vp -> fds = uml_vector_user_open (vp -> unit , vp -> parsed );
1200
1231
1201
1232
if (vp -> fds == NULL )
@@ -1267,8 +1298,11 @@ static int vector_net_open(struct net_device *dev)
1267
1298
if (!uml_raw_enable_qdisc_bypass (vp -> fds -> rx_fd ))
1268
1299
vp -> options |= VECTOR_BPF ;
1269
1300
}
1270
- if ((vp -> options & VECTOR_BPF ) != 0 )
1271
- vp -> bpf = uml_vector_default_bpf (vp -> fds -> rx_fd , dev -> dev_addr );
1301
+ if (((vp -> options & VECTOR_BPF ) != 0 ) && (vp -> bpf == NULL ))
1302
+ vp -> bpf = uml_vector_default_bpf (dev -> dev_addr );
1303
+
1304
+ if (vp -> bpf != NULL )
1305
+ uml_vector_attach_bpf (vp -> fds -> rx_fd , vp -> bpf );
1272
1306
1273
1307
netif_start_queue (dev );
1274
1308
@@ -1347,6 +1381,65 @@ static void vector_net_get_drvinfo(struct net_device *dev,
1347
1381
strlcpy (info -> version , DRIVER_VERSION , sizeof (info -> version ));
1348
1382
}
1349
1383
1384
+ static int vector_net_load_bpf_flash (struct net_device * dev ,
1385
+ struct ethtool_flash * efl )
1386
+ {
1387
+ struct vector_private * vp = netdev_priv (dev );
1388
+ struct vector_device * vdevice ;
1389
+ const struct firmware * fw ;
1390
+ int result = 0 ;
1391
+
1392
+ if (!(vp -> options & VECTOR_BPF_FLASH )) {
1393
+ netdev_err (dev , "loading firmware not permitted: %s\n" , efl -> data );
1394
+ return -1 ;
1395
+ }
1396
+
1397
+ spin_lock (& vp -> lock );
1398
+
1399
+ if (vp -> bpf != NULL ) {
1400
+ if (vp -> opened )
1401
+ uml_vector_detach_bpf (vp -> fds -> rx_fd , vp -> bpf );
1402
+ kfree (vp -> bpf -> filter );
1403
+ vp -> bpf -> filter = NULL ;
1404
+ } else {
1405
+ vp -> bpf = kmalloc (sizeof (struct sock_fprog ), GFP_KERNEL );
1406
+ if (vp -> bpf == NULL ) {
1407
+ netdev_err (dev , "failed to allocate memory for firmware\n" );
1408
+ goto flash_fail ;
1409
+ }
1410
+ }
1411
+
1412
+ vdevice = find_device (vp -> unit );
1413
+
1414
+ if (request_firmware (& fw , efl -> data , & vdevice -> pdev .dev ))
1415
+ goto flash_fail ;
1416
+
1417
+ vp -> bpf -> filter = kmemdup (fw -> data , fw -> size , GFP_KERNEL );
1418
+ if (!vp -> bpf -> filter )
1419
+ goto free_buffer ;
1420
+
1421
+ vp -> bpf -> len = fw -> size / sizeof (struct sock_filter );
1422
+ release_firmware (fw );
1423
+
1424
+ if (vp -> opened )
1425
+ result = uml_vector_attach_bpf (vp -> fds -> rx_fd , vp -> bpf );
1426
+
1427
+ spin_unlock (& vp -> lock );
1428
+
1429
+ return result ;
1430
+
1431
+ free_buffer :
1432
+ release_firmware (fw );
1433
+
1434
+ flash_fail :
1435
+ spin_unlock (& vp -> lock );
1436
+ if (vp -> bpf != NULL )
1437
+ kfree (vp -> bpf -> filter );
1438
+ kfree (vp -> bpf );
1439
+ vp -> bpf = NULL ;
1440
+ return -1 ;
1441
+ }
1442
+
1350
1443
static void vector_get_ringparam (struct net_device * netdev ,
1351
1444
struct ethtool_ringparam * ring )
1352
1445
{
@@ -1424,6 +1517,7 @@ static const struct ethtool_ops vector_net_ethtool_ops = {
1424
1517
.get_ethtool_stats = vector_get_ethtool_stats ,
1425
1518
.get_coalesce = vector_get_coalesce ,
1426
1519
.set_coalesce = vector_set_coalesce ,
1520
+ .flash_device = vector_net_load_bpf_flash ,
1427
1521
};
1428
1522
1429
1523
@@ -1528,8 +1622,9 @@ static void vector_eth_configure(
1528
1622
.in_write_poll = false,
1529
1623
.coalesce = 2 ,
1530
1624
.req_size = get_req_size (def ),
1531
- .in_error = false
1532
- });
1625
+ .in_error = false,
1626
+ .bpf = NULL
1627
+ });
1533
1628
1534
1629
dev -> features = dev -> hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST );
1535
1630
tasklet_init (& vp -> tx_poll , vector_tx_poll , (unsigned long )vp );
0 commit comments