Skip to content

Commit 0492d85

Browse files
committed
netfilter: flowtable: Fix QinQ and pppoe support for inet table
nf_flow_offload_inet_hook() does not check for 802.1q and PPPoE. Fetch inner ethertype from these encapsulation protocols. Fixes: 72efd58 ("netfilter: flowtable: add pppoe support") Fixes: 4cd91f7 ("netfilter: flowtable: add vlan support") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent dea2d93 commit 0492d85

3 files changed

Lines changed: 35 additions & 18 deletions

File tree

include/net/netfilter/nf_flow_table.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/netfilter/nf_conntrack_tuple_common.h>
1111
#include <net/flow_offload.h>
1212
#include <net/dst.h>
13+
#include <linux/if_pppox.h>
14+
#include <linux/ppp_defs.h>
1315

1416
struct nf_flowtable;
1517
struct nf_flow_rule;
@@ -317,4 +319,20 @@ int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
317319
int nf_flow_table_offload_init(void);
318320
void nf_flow_table_offload_exit(void);
319321

322+
static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
323+
{
324+
__be16 proto;
325+
326+
proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
327+
sizeof(struct pppoe_hdr)));
328+
switch (proto) {
329+
case htons(PPP_IP):
330+
return htons(ETH_P_IP);
331+
case htons(PPP_IPV6):
332+
return htons(ETH_P_IPV6);
333+
}
334+
335+
return 0;
336+
}
337+
320338
#endif /* _NF_FLOW_TABLE_H */

net/netfilter/nf_flow_table_inet.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,29 @@
66
#include <linux/rhashtable.h>
77
#include <net/netfilter/nf_flow_table.h>
88
#include <net/netfilter/nf_tables.h>
9+
#include <linux/if_vlan.h>
910

1011
static unsigned int
1112
nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
1213
const struct nf_hook_state *state)
1314
{
15+
struct vlan_ethhdr *veth;
16+
__be16 proto;
17+
1418
switch (skb->protocol) {
19+
case htons(ETH_P_8021Q):
20+
veth = (struct vlan_ethhdr *)skb_mac_header(skb);
21+
proto = veth->h_vlan_encapsulated_proto;
22+
break;
23+
case htons(ETH_P_PPP_SES):
24+
proto = nf_flow_pppoe_proto(skb);
25+
break;
26+
default:
27+
proto = skb->protocol;
28+
break;
29+
}
30+
31+
switch (proto) {
1532
case htons(ETH_P_IP):
1633
return nf_flow_offload_ip_hook(priv, skb, state);
1734
case htons(ETH_P_IPV6):

net/netfilter/nf_flow_table_ip.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
#include <linux/ipv6.h>
99
#include <linux/netdevice.h>
1010
#include <linux/if_ether.h>
11-
#include <linux/if_pppox.h>
12-
#include <linux/ppp_defs.h>
1311
#include <net/ip.h>
1412
#include <net/ipv6.h>
1513
#include <net/ip6_route.h>
@@ -239,22 +237,6 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
239237
return NF_STOLEN;
240238
}
241239

242-
static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
243-
{
244-
__be16 proto;
245-
246-
proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
247-
sizeof(struct pppoe_hdr)));
248-
switch (proto) {
249-
case htons(PPP_IP):
250-
return htons(ETH_P_IP);
251-
case htons(PPP_IPV6):
252-
return htons(ETH_P_IPV6);
253-
}
254-
255-
return 0;
256-
}
257-
258240
static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
259241
u32 *offset)
260242
{

0 commit comments

Comments
 (0)