@@ -19,40 +19,31 @@ static LIST_HEAD(flowtables);
19
19
20
20
static void
21
21
flow_offload_fill_dir (struct flow_offload * flow , struct nf_conn * ct ,
22
- struct nf_flow_route * route ,
23
22
enum flow_offload_tuple_dir dir )
24
23
{
25
24
struct flow_offload_tuple * ft = & flow -> tuplehash [dir ].tuple ;
26
25
struct nf_conntrack_tuple * ctt = & ct -> tuplehash [dir ].tuple ;
27
- struct dst_entry * other_dst = route -> tuple [!dir ].dst ;
28
- struct dst_entry * dst = route -> tuple [dir ].dst ;
29
26
30
27
ft -> dir = dir ;
31
28
32
29
switch (ctt -> src .l3num ) {
33
30
case NFPROTO_IPV4 :
34
31
ft -> src_v4 = ctt -> src .u3 .in ;
35
32
ft -> dst_v4 = ctt -> dst .u3 .in ;
36
- ft -> mtu = ip_dst_mtu_maybe_forward (dst , true);
37
33
break ;
38
34
case NFPROTO_IPV6 :
39
35
ft -> src_v6 = ctt -> src .u3 .in6 ;
40
36
ft -> dst_v6 = ctt -> dst .u3 .in6 ;
41
- ft -> mtu = ip6_dst_mtu_forward (dst );
42
37
break ;
43
38
}
44
39
45
40
ft -> l3proto = ctt -> src .l3num ;
46
41
ft -> l4proto = ctt -> dst .protonum ;
47
42
ft -> src_port = ctt -> src .u .tcp .port ;
48
43
ft -> dst_port = ctt -> dst .u .tcp .port ;
49
-
50
- ft -> iifidx = other_dst -> dev -> ifindex ;
51
- ft -> dst_cache = dst ;
52
44
}
53
45
54
- struct flow_offload *
55
- flow_offload_alloc (struct nf_conn * ct , struct nf_flow_route * route )
46
+ struct flow_offload * flow_offload_alloc (struct nf_conn * ct )
56
47
{
57
48
struct flow_offload * flow ;
58
49
@@ -64,16 +55,10 @@ flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route)
64
55
if (!flow )
65
56
goto err_ct_refcnt ;
66
57
67
- if (!dst_hold_safe (route -> tuple [FLOW_OFFLOAD_DIR_ORIGINAL ].dst ))
68
- goto err_dst_cache_original ;
69
-
70
- if (!dst_hold_safe (route -> tuple [FLOW_OFFLOAD_DIR_REPLY ].dst ))
71
- goto err_dst_cache_reply ;
72
-
73
58
flow -> ct = ct ;
74
59
75
- flow_offload_fill_dir (flow , ct , route , FLOW_OFFLOAD_DIR_ORIGINAL );
76
- flow_offload_fill_dir (flow , ct , route , FLOW_OFFLOAD_DIR_REPLY );
60
+ flow_offload_fill_dir (flow , ct , FLOW_OFFLOAD_DIR_ORIGINAL );
61
+ flow_offload_fill_dir (flow , ct , FLOW_OFFLOAD_DIR_REPLY );
77
62
78
63
if (ct -> status & IPS_SRC_NAT )
79
64
flow -> flags |= FLOW_OFFLOAD_SNAT ;
@@ -82,17 +67,63 @@ flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route)
82
67
83
68
return flow ;
84
69
85
- err_dst_cache_reply :
86
- dst_release (route -> tuple [FLOW_OFFLOAD_DIR_ORIGINAL ].dst );
87
- err_dst_cache_original :
88
- kfree (flow );
89
70
err_ct_refcnt :
90
71
nf_ct_put (ct );
91
72
92
73
return NULL ;
93
74
}
94
75
EXPORT_SYMBOL_GPL (flow_offload_alloc );
95
76
77
+ static int flow_offload_fill_route (struct flow_offload * flow ,
78
+ const struct nf_flow_route * route ,
79
+ enum flow_offload_tuple_dir dir )
80
+ {
81
+ struct flow_offload_tuple * flow_tuple = & flow -> tuplehash [dir ].tuple ;
82
+ struct dst_entry * other_dst = route -> tuple [!dir ].dst ;
83
+ struct dst_entry * dst = route -> tuple [dir ].dst ;
84
+
85
+ if (!dst_hold_safe (route -> tuple [dir ].dst ))
86
+ return -1 ;
87
+
88
+ switch (flow_tuple -> l3proto ) {
89
+ case NFPROTO_IPV4 :
90
+ flow_tuple -> mtu = ip_dst_mtu_maybe_forward (dst , true);
91
+ break ;
92
+ case NFPROTO_IPV6 :
93
+ flow_tuple -> mtu = ip6_dst_mtu_forward (dst );
94
+ break ;
95
+ }
96
+
97
+ flow_tuple -> iifidx = other_dst -> dev -> ifindex ;
98
+ flow_tuple -> dst_cache = dst ;
99
+
100
+ return 0 ;
101
+ }
102
+
103
+ int flow_offload_route_init (struct flow_offload * flow ,
104
+ const struct nf_flow_route * route )
105
+ {
106
+ int err ;
107
+
108
+ err = flow_offload_fill_route (flow , route , FLOW_OFFLOAD_DIR_ORIGINAL );
109
+ if (err < 0 )
110
+ return err ;
111
+
112
+ err = flow_offload_fill_route (flow , route , FLOW_OFFLOAD_DIR_REPLY );
113
+ if (err < 0 )
114
+ goto err_route_reply ;
115
+
116
+ flow -> type = NF_FLOW_OFFLOAD_ROUTE ;
117
+
118
+ return 0 ;
119
+
120
+ err_route_reply :
121
+ dst_release (route -> tuple [FLOW_OFFLOAD_DIR_ORIGINAL ].dst );
122
+
123
+ return err ;
124
+ }
125
+ EXPORT_SYMBOL_GPL (flow_offload_route_init );
126
+
96
127
static void flow_offload_fixup_tcp (struct ip_ct_tcp * tcp )
97
128
{
98
129
tcp -> state = TCP_CONNTRACK_ESTABLISHED ;
@@ -141,10 +172,21 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
141
172
flow_offload_fixup_ct_timeout (ct );
142
173
}
143
174
144
- void flow_offload_free (struct flow_offload * flow )
175
+ static void flow_offload_route_release (struct flow_offload * flow )
145
176
{
146
177
dst_release (flow -> tuplehash [FLOW_OFFLOAD_DIR_ORIGINAL ].tuple .dst_cache );
147
178
dst_release (flow -> tuplehash [FLOW_OFFLOAD_DIR_REPLY ].tuple .dst_cache );
179
+ }
180
+
181
+ void flow_offload_free (struct flow_offload * flow )
182
+ {
183
+ switch (flow -> type ) {
184
+ case NF_FLOW_OFFLOAD_ROUTE :
185
+ flow_offload_route_release (flow );
186
+ break ;
187
+ default :
188
+ break ;
189
+ }
148
190
if (flow -> flags & FLOW_OFFLOAD_DYING )
149
191
nf_ct_delete (flow -> ct , 0 , 0 );
150
192
nf_ct_put (flow -> ct );
0 commit comments