77
77
#include <net/net_namespace.h>
78
78
#include <net/netns/generic.h>
79
79
#include <net/sock.h>
80
+ #include <net/gro.h>
80
81
81
82
#include <linux/uaccess.h>
82
83
@@ -435,7 +436,7 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
435
436
if (skb -> len < len )
436
437
goto drop ;
437
438
438
- if (pskb_trim_rcsum (skb , len ))
439
+ if (! skb_is_gso ( skb ) && pskb_trim_rcsum (skb , len ))
439
440
goto drop ;
440
441
441
442
ph = pppoe_hdr (skb );
@@ -1173,6 +1174,105 @@ static struct pernet_operations pppoe_net_ops = {
1173
1174
.size = sizeof (struct pppoe_net ),
1174
1175
};
1175
1176
1177
+ static u16
1178
+ compare_pppoe_header (struct pppoe_hdr * phdr , struct pppoe_hdr * phdr2 )
1179
+ {
1180
+ return (__force __u16 )((phdr -> sid ^ phdr2 -> sid ) |
1181
+ (phdr -> tag [0 ].tag_type ^ phdr2 -> tag [0 ].tag_type ));
1182
+ }
1183
+
1184
+ static __be16 pppoe_hdr_proto (struct pppoe_hdr * phdr )
1185
+ {
1186
+ switch (phdr -> tag [0 ].tag_type ) {
1187
+ case cpu_to_be16 (PPP_IP ):
1188
+ return cpu_to_be16 (ETH_P_IP );
1189
+ case cpu_to_be16 (PPP_IPV6 ):
1190
+ return cpu_to_be16 (ETH_P_IPV6 );
1191
+ default :
1192
+ return 0 ;
1193
+ }
1194
+
1195
+ }
1196
+
1197
+ static struct sk_buff * pppoe_gro_receive (struct list_head * head ,
1198
+ struct sk_buff * skb )
1199
+ {
1200
+ const struct packet_offload * ptype ;
1201
+ unsigned int hlen , off_pppoe ;
1202
+ struct sk_buff * pp = NULL ;
1203
+ struct pppoe_hdr * phdr ;
1204
+ struct sk_buff * p ;
1205
+ __be16 type ;
1206
+ int flush = 1 ;
1207
+
1208
+ off_pppoe = skb_gro_offset (skb );
1209
+ hlen = off_pppoe + sizeof (* phdr ) + 2 ;
1210
+ phdr = skb_gro_header (skb , hlen , off_pppoe );
1211
+ if (unlikely (!phdr ))
1212
+ goto out ;
1213
+
1214
+ /* ignore packets with padding or invalid length */
1215
+ if (skb_gro_len (skb ) != be16_to_cpu (phdr -> length ) + hlen - 2 )
1216
+ goto out ;
1217
+
1218
+ NAPI_GRO_CB (skb )-> network_offsets [NAPI_GRO_CB (skb )-> encap_mark ] = hlen ;
1219
+
1220
+ type = pppoe_hdr_proto (phdr );
1221
+ if (!type )
1222
+ goto out ;
1223
+
1224
+ ptype = gro_find_receive_by_type (type );
1225
+ if (!ptype )
1226
+ goto out ;
1227
+
1228
+ flush = 0 ;
1229
+
1230
+ list_for_each_entry (p , head , list ) {
1231
+ struct pppoe_hdr * phdr2 ;
1232
+
1233
+ if (!NAPI_GRO_CB (p )-> same_flow )
1234
+ continue ;
1235
+
1236
+ phdr2 = (struct pppoe_hdr * )(p -> data + off_pppoe );
1237
+ if (compare_pppoe_header (phdr , phdr2 ))
1238
+ NAPI_GRO_CB (p )-> same_flow = 0 ;
1239
+ }
1240
+
1241
+ skb_gro_pull (skb , sizeof (* phdr ) + 2 );
1242
+ skb_gro_postpull_rcsum (skb , phdr , sizeof (* phdr ) + 2 );
1243
+
1244
+ pp = ptype -> callbacks .gro_receive (head , skb );
1245
+
1246
+ out :
1247
+ skb_gro_flush_final (skb , pp , flush );
1248
+
1249
+ return pp ;
1250
+ }
1251
+
1252
+ static int pppoe_gro_complete (struct sk_buff * skb , int nhoff )
1253
+ {
1254
+ struct pppoe_hdr * phdr = (struct pppoe_hdr * )(skb -> data + nhoff );
1255
+ __be16 type = pppoe_hdr_proto (phdr );
1256
+ struct packet_offload * ptype ;
1257
+ int err = - ENOENT ;
1258
+
1259
+ ptype = gro_find_complete_by_type (type );
1260
+ if (ptype )
1261
+ err = ptype -> callbacks .gro_complete (skb , nhoff +
1262
+ sizeof (* phdr ) + 2 );
1263
+
1264
+ return err ;
1265
+ }
1266
+
1267
+ static struct packet_offload pppoe_packet_offload __read_mostly = {
1268
+ .type = cpu_to_be16 (ETH_P_PPP_SES ),
1269
+ .priority = 10 ,
1270
+ .callbacks = {
1271
+ .gro_receive = pppoe_gro_receive ,
1272
+ .gro_complete = pppoe_gro_complete ,
1273
+ },
1274
+ };
1275
+
1176
1276
static int __init pppoe_init (void )
1177
1277
{
1178
1278
int err ;
@@ -1189,6 +1289,7 @@ static int __init pppoe_init(void)
1189
1289
if (err )
1190
1290
goto out_unregister_pppoe_proto ;
1191
1291
1292
+ dev_add_offload (& pppoe_packet_offload );
1192
1293
dev_add_pack (& pppoes_ptype );
1193
1294
dev_add_pack (& pppoed_ptype );
1194
1295
register_netdevice_notifier (& pppoe_notifier );
@@ -1208,6 +1309,7 @@ static void __exit pppoe_exit(void)
1208
1309
unregister_netdevice_notifier (& pppoe_notifier );
1209
1310
dev_remove_pack (& pppoed_ptype );
1210
1311
dev_remove_pack (& pppoes_ptype );
1312
+ dev_remove_offload (& pppoe_packet_offload );
1211
1313
unregister_pppox_proto (PX_PROTO_OE );
1212
1314
proto_unregister (& pppoe_sk_proto );
1213
1315
unregister_pernet_device (& pppoe_net_ops );
0 commit comments