28
28
#include <linux/workqueue.h>
29
29
#include <net/devlink.h>
30
30
#include <net/ip.h>
31
+ #include <net/flow_offload.h>
31
32
#include <uapi/linux/devlink.h>
32
33
#include <uapi/linux/ip.h>
33
34
#include <uapi/linux/udp.h>
@@ -71,6 +72,98 @@ static const struct file_operations nsim_dev_take_snapshot_fops = {
71
72
.llseek = generic_file_llseek ,
72
73
};
73
74
75
+ static ssize_t nsim_dev_trap_fa_cookie_read (struct file * file ,
76
+ char __user * data ,
77
+ size_t count , loff_t * ppos )
78
+ {
79
+ struct nsim_dev * nsim_dev = file -> private_data ;
80
+ struct flow_action_cookie * fa_cookie ;
81
+ unsigned int buf_len ;
82
+ ssize_t ret ;
83
+ char * buf ;
84
+
85
+ spin_lock (& nsim_dev -> fa_cookie_lock );
86
+ fa_cookie = nsim_dev -> fa_cookie ;
87
+ if (!fa_cookie ) {
88
+ ret = - EINVAL ;
89
+ goto errout ;
90
+ }
91
+ buf_len = fa_cookie -> cookie_len * 2 ;
92
+ buf = kmalloc (buf_len , GFP_ATOMIC );
93
+ if (!buf ) {
94
+ ret = - ENOMEM ;
95
+ goto errout ;
96
+ }
97
+ bin2hex (buf , fa_cookie -> cookie , fa_cookie -> cookie_len );
98
+ spin_unlock (& nsim_dev -> fa_cookie_lock );
99
+
100
+ ret = simple_read_from_buffer (data , count , ppos , buf , buf_len );
101
+
102
+ kfree (buf );
103
+ return ret ;
104
+
105
+ errout :
106
+ spin_unlock (& nsim_dev -> fa_cookie_lock );
107
+ return ret ;
108
+ }
109
+
110
+ static ssize_t nsim_dev_trap_fa_cookie_write (struct file * file ,
111
+ const char __user * data ,
112
+ size_t count , loff_t * ppos )
113
+ {
114
+ struct nsim_dev * nsim_dev = file -> private_data ;
115
+ struct flow_action_cookie * fa_cookie ;
116
+ size_t cookie_len ;
117
+ ssize_t ret ;
118
+ char * buf ;
119
+
120
+ if (* ppos != 0 )
121
+ return - EINVAL ;
122
+ cookie_len = (count - 1 ) / 2 ;
123
+ if ((count - 1 ) % 2 )
124
+ return - EINVAL ;
125
+ buf = kmalloc (count , GFP_KERNEL | __GFP_NOWARN );
126
+ if (!buf )
127
+ return - ENOMEM ;
128
+
129
+ ret = simple_write_to_buffer (buf , count , ppos , data , count );
130
+ if (ret < 0 )
131
+ goto free_buf ;
132
+
133
+ fa_cookie = kmalloc (sizeof (* fa_cookie ) + cookie_len ,
134
+ GFP_KERNEL | __GFP_NOWARN );
135
+ if (!fa_cookie ) {
136
+ ret = - ENOMEM ;
137
+ goto free_buf ;
138
+ }
139
+
140
+ fa_cookie -> cookie_len = cookie_len ;
141
+ ret = hex2bin (fa_cookie -> cookie , buf , cookie_len );
142
+ if (ret )
143
+ goto free_fa_cookie ;
144
+ kfree (buf );
145
+
146
+ spin_lock (& nsim_dev -> fa_cookie_lock );
147
+ kfree (nsim_dev -> fa_cookie );
148
+ nsim_dev -> fa_cookie = fa_cookie ;
149
+ spin_unlock (& nsim_dev -> fa_cookie_lock );
150
+
151
+ return count ;
152
+
153
+ free_fa_cookie :
154
+ kfree (fa_cookie );
155
+ free_buf :
156
+ kfree (buf );
157
+ return ret ;
158
+ }
159
+
160
+ static const struct file_operations nsim_dev_trap_fa_cookie_fops = {
161
+ .open = simple_open ,
162
+ .read = nsim_dev_trap_fa_cookie_read ,
163
+ .write = nsim_dev_trap_fa_cookie_write ,
164
+ .llseek = generic_file_llseek ,
165
+ };
166
+
74
167
static int nsim_dev_debugfs_init (struct nsim_dev * nsim_dev )
75
168
{
76
169
char dev_ddir_name [sizeof (DRV_NAME ) + 10 ];
@@ -97,6 +190,8 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
97
190
& nsim_dev -> dont_allow_reload );
98
191
debugfs_create_bool ("fail_reload" , 0600 , nsim_dev -> ddir ,
99
192
& nsim_dev -> fail_reload );
193
+ debugfs_create_file ("trap_flow_action_cookie" , 0600 , nsim_dev -> ddir ,
194
+ nsim_dev , & nsim_dev_trap_fa_cookie_fops );
100
195
return 0 ;
101
196
}
102
197
@@ -288,6 +383,10 @@ enum {
288
383
DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
289
384
DEVLINK_TRAP_GROUP_GENERIC(_group_id), \
290
385
NSIM_TRAP_METADATA)
386
+ #define NSIM_TRAP_DROP_EXT (_id , _group_id , _metadata ) \
387
+ DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
388
+ DEVLINK_TRAP_GROUP_GENERIC(_group_id), \
389
+ NSIM_TRAP_METADATA | (_metadata))
291
390
#define NSIM_TRAP_EXCEPTION (_id , _group_id ) \
292
391
DEVLINK_TRAP_GENERIC(EXCEPTION, TRAP, _id, \
293
392
DEVLINK_TRAP_GROUP_GENERIC(_group_id), \
@@ -309,6 +408,10 @@ static const struct devlink_trap nsim_traps_arr[] = {
309
408
NSIM_TRAP_DROP (BLACKHOLE_ROUTE , L3_DROPS ),
310
409
NSIM_TRAP_EXCEPTION (TTL_ERROR , L3_DROPS ),
311
410
NSIM_TRAP_DROP (TAIL_DROP , BUFFER_DROPS ),
411
+ NSIM_TRAP_DROP_EXT (INGRESS_FLOW_ACTION_DROP , ACL_DROPS ,
412
+ DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE ),
413
+ NSIM_TRAP_DROP_EXT (EGRESS_FLOW_ACTION_DROP , ACL_DROPS ,
414
+ DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE ),
312
415
};
313
416
314
417
#define NSIM_TRAP_L4_DATA_LEN 100
@@ -366,8 +469,13 @@ static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
366
469
367
470
spin_lock (& nsim_trap_data -> trap_lock );
368
471
for (i = 0 ; i < ARRAY_SIZE (nsim_traps_arr ); i ++ ) {
472
+ struct flow_action_cookie * fa_cookie = NULL ;
369
473
struct nsim_trap_item * nsim_trap_item ;
370
474
struct sk_buff * skb ;
475
+ bool has_fa_cookie ;
476
+
477
+ has_fa_cookie = nsim_traps_arr [i ].metadata_cap &
478
+ DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE ;
371
479
372
480
nsim_trap_item = & nsim_trap_data -> trap_items_arr [i ];
373
481
if (nsim_trap_item -> action == DEVLINK_TRAP_ACTION_DROP )
@@ -383,10 +491,12 @@ static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
383
491
* softIRQs to prevent lockdep from complaining about
384
492
* "incosistent lock state".
385
493
*/
386
- local_bh_disable ();
494
+
495
+ spin_lock_bh (& nsim_dev -> fa_cookie_lock );
496
+ fa_cookie = has_fa_cookie ? nsim_dev -> fa_cookie : NULL ;
387
497
devlink_trap_report (devlink , skb , nsim_trap_item -> trap_ctx ,
388
- & nsim_dev_port -> devlink_port , NULL );
389
- local_bh_enable ( );
498
+ & nsim_dev_port -> devlink_port , fa_cookie );
499
+ spin_unlock_bh ( & nsim_dev -> fa_cookie_lock );
390
500
consume_skb (skb );
391
501
}
392
502
spin_unlock (& nsim_trap_data -> trap_lock );
@@ -780,6 +890,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
780
890
nsim_dev -> fw_update_status = true;
781
891
nsim_dev -> max_macs = NSIM_DEV_MAX_MACS_DEFAULT ;
782
892
nsim_dev -> test1 = NSIM_DEV_TEST1_DEFAULT ;
893
+ spin_lock_init (& nsim_dev -> fa_cookie_lock );
783
894
784
895
dev_set_drvdata (& nsim_bus_dev -> dev , nsim_dev );
785
896
0 commit comments