kernel: check dst of flow offloading table
Flow offload dst can become invalid after the route cache is created. dst_check() in packet path is necessary to prevent packet drop. Signed-off-by: Ritaro Takenaka <ritarot634@gmail.com>
This commit is contained in:
		 Ritaro Takenaka
					Ritaro Takenaka
				
			
				
					committed by
					
						 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
			
				
	
			
			
			 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
						parent
						
							78b7515c2e
						
					
				
				
					commit
					6d891adf39
				
			| @@ -0,0 +1,97 @@ | |||||||
|  | From 94936600fce68845edea66ae6d06ad12d6469e0b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ritaro Takenaka <ritarot634@gmail.com> | ||||||
|  | Date: Tue, 31 May 2022 00:25:08 +0900 | ||||||
|  | Subject: [PATCH] netfilter: flowtable: add check_dst in packet path | ||||||
|  |  | ||||||
|  | Flow offload dst can become invalid after the route cache is created. | ||||||
|  | dst_check() in packet path is necessary to prevent packet drop. | ||||||
|  |  | ||||||
|  | [ Upstream commit  2738d9d963bd1f06d5114c2b4fa5771a95703991 | ||||||
|  |                    8b9229d15877ec77775633f058d14145f6eb98fa | ||||||
|  |                    e5075c0badaaac245a6fa0b4625b5cd714d8ade3 ] | ||||||
|  |  | ||||||
|  | Signed-off-by: Ritaro Takenaka <ritarot634@gmail.com> | ||||||
|  | --- | ||||||
|  |  include/net/netfilter/nf_flow_table.h |  5 ++++- | ||||||
|  |  net/netfilter/nf_flow_table_core.c    | 13 +++++++++++++ | ||||||
|  |  net/netfilter/nf_flow_table_ip.c      | 12 ++---------- | ||||||
|  |  3 files changed, 19 insertions(+), 11 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/net/netfilter/nf_flow_table.h | ||||||
|  | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
|  | @@ -56,7 +56,10 @@ struct flow_offload_tuple { | ||||||
|  |   | ||||||
|  |  	u16				mtu; | ||||||
|  |   | ||||||
|  | -	struct dst_entry		*dst_cache; | ||||||
|  | +	struct { | ||||||
|  | +		struct dst_entry *dst_cache; | ||||||
|  | +		u32		dst_cookie; | ||||||
|  | +	}; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct flow_offload_tuple_rhash { | ||||||
|  | --- a/net/netfilter/nf_flow_table_core.c | ||||||
|  | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
|  | @@ -23,6 +23,18 @@ struct flow_offload_entry { | ||||||
|  |  static DEFINE_MUTEX(flowtable_lock); | ||||||
|  |  static LIST_HEAD(flowtables); | ||||||
|  |   | ||||||
|  | +static u32 flow_offload_dst_cookie(struct flow_offload_tuple *flow_tuple) | ||||||
|  | +{ | ||||||
|  | +	const struct rt6_info *rt; | ||||||
|  | + | ||||||
|  | +	if (flow_tuple->l3proto == NFPROTO_IPV6) { | ||||||
|  | +		rt = (const struct rt6_info *)flow_tuple->dst_cache; | ||||||
|  | +		return rt6_get_cookie(rt); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void | ||||||
|  |  flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct, | ||||||
|  |  		      struct nf_flow_route *route, | ||||||
|  | @@ -55,6 +67,7 @@ flow_offload_fill_dir(struct flow_offloa | ||||||
|  |   | ||||||
|  |  	ft->iifidx = other_dst->dev->ifindex; | ||||||
|  |  	ft->dst_cache = dst; | ||||||
|  | +	ft->dst_cookie = flow_offload_dst_cookie(ft); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  struct flow_offload * | ||||||
|  | --- a/net/netfilter/nf_flow_table_ip.c | ||||||
|  | +++ b/net/netfilter/nf_flow_table_ip.c | ||||||
|  | @@ -215,14 +215,6 @@ static bool nf_flow_exceeds_mtu(const st | ||||||
|  |  	return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int nf_flow_offload_dst_check(struct dst_entry *dst) | ||||||
|  | -{ | ||||||
|  | -	if (unlikely(dst_xfrm(dst))) | ||||||
|  | -		return dst_check(dst, 0) ? 0 : -1; | ||||||
|  | - | ||||||
|  | -	return 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb, | ||||||
|  |  				      const struct nf_hook_state *state, | ||||||
|  |  				      struct dst_entry *dst) | ||||||
|  | @@ -273,7 +265,7 @@ nf_flow_offload_ip_hook(void *priv, stru | ||||||
|  |  	if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff)) | ||||||
|  |  		return NF_ACCEPT; | ||||||
|  |   | ||||||
|  | -	if (nf_flow_offload_dst_check(&rt->dst)) { | ||||||
|  | +	if (!dst_check(&rt->dst, 0)) { | ||||||
|  |  		flow_offload_teardown(flow); | ||||||
|  |  		return NF_ACCEPT; | ||||||
|  |  	} | ||||||
|  | @@ -500,7 +492,7 @@ nf_flow_offload_ipv6_hook(void *priv, st | ||||||
|  |  				sizeof(*ip6h))) | ||||||
|  |  		return NF_ACCEPT; | ||||||
|  |   | ||||||
|  | -	if (nf_flow_offload_dst_check(&rt->dst)) { | ||||||
|  | +	if (!dst_check(&rt->dst, tuplehash->tuple.dst_cookie)) { | ||||||
|  |  		flow_offload_teardown(flow); | ||||||
|  |  		return NF_ACCEPT; | ||||||
|  |  	} | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -160,6 +160,8 @@ struct nf_flow_table_hw { | @@ -163,6 +163,8 @@ struct nf_flow_table_hw { | ||||||
|  int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload); |  int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload); | ||||||
|  void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload); |  void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload); | ||||||
|   |   | ||||||
| @@ -19,7 +19,7 @@ | |||||||
|   |   | ||||||
|  struct flow_offload_entry { |  struct flow_offload_entry { | ||||||
|  	struct flow_offload	flow; |  	struct flow_offload	flow; | ||||||
| @@ -164,6 +165,22 @@ void flow_offload_free(struct flow_offlo | @@ -177,6 +178,22 @@ void flow_offload_free(struct flow_offlo | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(flow_offload_free); |  EXPORT_SYMBOL_GPL(flow_offload_free); | ||||||
|   |   | ||||||
| @@ -52,7 +52,7 @@ | |||||||
|  /* For layer 4 checksum field offset. */ |  /* For layer 4 checksum field offset. */ | ||||||
|  #include <linux/tcp.h> |  #include <linux/tcp.h> | ||||||
|  #include <linux/udp.h> |  #include <linux/udp.h> | ||||||
| @@ -296,6 +297,7 @@ nf_flow_offload_ip_hook(void *priv, stru | @@ -288,6 +289,7 @@ nf_flow_offload_ip_hook(void *priv, stru | ||||||
|  	skb->dev = outdev; |  	skb->dev = outdev; | ||||||
|  	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); |  	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); | ||||||
|  	skb_dst_set_noref(skb, &rt->dst); |  	skb_dst_set_noref(skb, &rt->dst); | ||||||
| @@ -60,7 +60,7 @@ | |||||||
|  	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); |  	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); | ||||||
|   |   | ||||||
|  	return NF_STOLEN; |  	return NF_STOLEN; | ||||||
| @@ -526,6 +528,7 @@ nf_flow_offload_ipv6_hook(void *priv, st | @@ -518,6 +520,7 @@ nf_flow_offload_ipv6_hook(void *priv, st | ||||||
|  	skb->dev = outdev; |  	skb->dev = outdev; | ||||||
|  	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); |  	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); | ||||||
|  	skb_dst_set_noref(skb, &rt->dst); |  	skb_dst_set_noref(skb, &rt->dst); | ||||||
|   | |||||||
| @@ -536,7 +536,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  #include <net/netfilter/nf_flow_table.h> |  #include <net/netfilter/nf_flow_table.h> | ||||||
|  #include <net/netfilter/nf_conntrack.h> |  #include <net/netfilter/nf_conntrack.h> | ||||||
|  #include <net/netfilter/nf_conntrack_core.h> |  #include <net/netfilter/nf_conntrack_core.h> | ||||||
| @@ -338,8 +337,7 @@ flow_offload_lookup(struct nf_flowtable | @@ -351,8 +350,7 @@ flow_offload_lookup(struct nf_flowtable | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(flow_offload_lookup); |  EXPORT_SYMBOL_GPL(flow_offload_lookup); | ||||||
|   |   | ||||||
| @@ -546,7 +546,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		      void (*iter)(struct flow_offload *flow, void *data), |  		      void (*iter)(struct flow_offload *flow, void *data), | ||||||
|  		      void *data) |  		      void *data) | ||||||
|  { |  { | ||||||
| @@ -372,6 +370,7 @@ nf_flow_table_iterate(struct nf_flowtabl | @@ -385,6 +383,7 @@ nf_flow_table_iterate(struct nf_flowtabl | ||||||
|   |   | ||||||
|  	return err; |  	return err; | ||||||
|  } |  } | ||||||
| @@ -576,7 +576,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +#endif /* _XT_FLOWOFFLOAD_H */ | +#endif /* _XT_FLOWOFFLOAD_H */ | ||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -130,6 +130,10 @@ static inline void flow_offload_dead(str | @@ -133,6 +133,10 @@ static inline void flow_offload_dead(str | ||||||
|  	flow->flags |= FLOW_OFFLOAD_DYING; |  	flow->flags |= FLOW_OFFLOAD_DYING; | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  enum flow_offload_tuple_dir { |  enum flow_offload_tuple_dir { | ||||||
| @@ -68,6 +74,7 @@ struct flow_offload_tuple_rhash { | @@ -71,6 +77,7 @@ struct flow_offload_tuple_rhash { | ||||||
|  #define FLOW_OFFLOAD_DNAT	0x2 |  #define FLOW_OFFLOAD_DNAT	0x2 | ||||||
|  #define FLOW_OFFLOAD_DYING	0x4 |  #define FLOW_OFFLOAD_DYING	0x4 | ||||||
|  #define FLOW_OFFLOAD_TEARDOWN	0x8 |  #define FLOW_OFFLOAD_TEARDOWN	0x8 | ||||||
| @@ -85,7 +85,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|   |   | ||||||
|  struct flow_offload { |  struct flow_offload { | ||||||
|  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; |  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; | ||||||
| @@ -120,6 +127,22 @@ unsigned int nf_flow_offload_ip_hook(voi | @@ -123,6 +130,22 @@ unsigned int nf_flow_offload_ip_hook(voi | ||||||
|  unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, |  unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, | ||||||
|  				       const struct nf_hook_state *state); |  				       const struct nf_hook_state *state); | ||||||
|   |   | ||||||
| @@ -156,7 +156,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o |  obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o | ||||||
| --- a/net/netfilter/nf_flow_table_core.c | --- a/net/netfilter/nf_flow_table_core.c | ||||||
| +++ b/net/netfilter/nf_flow_table_core.c | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
| @@ -248,10 +248,16 @@ static inline bool nf_flow_has_expired(c | @@ -261,10 +261,16 @@ static inline bool nf_flow_has_expired(c | ||||||
|  	return nf_flow_timeout_delta(flow->timeout) <= 0; |  	return nf_flow_timeout_delta(flow->timeout) <= 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -173,7 +173,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|   |   | ||||||
|  	rhashtable_remove_fast(&flow_table->rhashtable, |  	rhashtable_remove_fast(&flow_table->rhashtable, | ||||||
|  			       &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, |  			       &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, | ||||||
| @@ -271,6 +277,9 @@ static void flow_offload_del(struct nf_f | @@ -284,6 +290,9 @@ static void flow_offload_del(struct nf_f | ||||||
|  	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) |  	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) | ||||||
|  		flow_offload_fixup_ct_state(e->ct); |  		flow_offload_fixup_ct_state(e->ct); | ||||||
|   |   | ||||||
| @@ -183,7 +183,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  	flow_offload_free(flow); |  	flow_offload_free(flow); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -361,6 +370,9 @@ static void nf_flow_offload_gc_step(stru | @@ -374,6 +383,9 @@ static void nf_flow_offload_gc_step(stru | ||||||
|  	if (!teardown) |  	if (!teardown) | ||||||
|  		nf_ct_offload_timeout(flow); |  		nf_ct_offload_timeout(flow); | ||||||
|   |   | ||||||
| @@ -193,7 +193,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  	if (nf_flow_has_expired(flow) || teardown) |  	if (nf_flow_has_expired(flow) || teardown) | ||||||
|  		flow_offload_del(flow_table, flow); |  		flow_offload_del(flow_table, flow); | ||||||
|  } |  } | ||||||
| @@ -490,10 +502,43 @@ int nf_flow_dnat_port(const struct flow_ | @@ -503,10 +515,43 @@ int nf_flow_dnat_port(const struct flow_ | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(nf_flow_dnat_port); |  EXPORT_SYMBOL_GPL(nf_flow_dnat_port); | ||||||
|   |   | ||||||
| @@ -237,7 +237,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  	INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); |  	INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); | ||||||
|   |   | ||||||
|  	err = rhashtable_init(&flowtable->rhashtable, |  	err = rhashtable_init(&flowtable->rhashtable, | ||||||
| @@ -534,6 +579,8 @@ static void nf_flow_table_iterate_cleanu | @@ -547,6 +592,8 @@ static void nf_flow_table_iterate_cleanu | ||||||
|  { |  { | ||||||
|  	nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); |  	nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); | ||||||
|  	flush_delayed_work(&flowtable->gc_work); |  	flush_delayed_work(&flowtable->gc_work); | ||||||
| @@ -246,7 +246,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  void nf_flow_table_cleanup(struct net_device *dev) |  void nf_flow_table_cleanup(struct net_device *dev) | ||||||
| @@ -547,6 +594,26 @@ void nf_flow_table_cleanup(struct net_de | @@ -560,6 +607,26 @@ void nf_flow_table_cleanup(struct net_de | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); |  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); | ||||||
|   |   | ||||||
| @@ -273,7 +273,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  void nf_flow_table_free(struct nf_flowtable *flow_table) |  void nf_flow_table_free(struct nf_flowtable *flow_table) | ||||||
|  { |  { | ||||||
|  	mutex_lock(&flowtable_lock); |  	mutex_lock(&flowtable_lock); | ||||||
| @@ -556,9 +623,58 @@ void nf_flow_table_free(struct nf_flowta | @@ -569,9 +636,58 @@ void nf_flow_table_free(struct nf_flowta | ||||||
|  	nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); |  	nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); | ||||||
|  	nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); |  	nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); | ||||||
|  	rhashtable_destroy(&flow_table->rhashtable); |  	rhashtable_destroy(&flow_table->rhashtable); | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	int			(*ndo_get_phys_port_id)(struct net_device *dev, |  	int			(*ndo_get_phys_port_id)(struct net_device *dev, | ||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -85,6 +85,21 @@ struct flow_offload { | @@ -88,6 +88,21 @@ struct flow_offload { | ||||||
|  	}; |  	}; | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  |  | ||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -75,6 +75,7 @@ struct flow_offload_tuple_rhash { | @@ -78,6 +78,7 @@ struct flow_offload_tuple_rhash { | ||||||
|  #define FLOW_OFFLOAD_DYING	0x4 |  #define FLOW_OFFLOAD_DYING	0x4 | ||||||
|  #define FLOW_OFFLOAD_TEARDOWN	0x8 |  #define FLOW_OFFLOAD_TEARDOWN	0x8 | ||||||
|  #define FLOW_OFFLOAD_HW		0x10 |  #define FLOW_OFFLOAD_HW		0x10 | ||||||
| @@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; |  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; | ||||||
| --- a/net/netfilter/nf_flow_table_core.c | --- a/net/netfilter/nf_flow_table_core.c | ||||||
| +++ b/net/netfilter/nf_flow_table_core.c | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
| @@ -370,7 +370,7 @@ static void nf_flow_offload_gc_step(stru | @@ -383,7 +383,7 @@ static void nf_flow_offload_gc_step(stru | ||||||
|  	if (!teardown) |  	if (!teardown) | ||||||
|  		nf_ct_offload_timeout(flow); |  		nf_ct_offload_timeout(flow); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  |  | ||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -80,9 +80,10 @@ struct flow_offload_tuple_rhash { | @@ -83,9 +83,10 @@ struct flow_offload_tuple_rhash { | ||||||
|  struct flow_offload { |  struct flow_offload { | ||||||
|  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; |  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX]; | ||||||
|  	u32					flags; |  	u32					flags; | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  |  | ||||||
| --- a/include/net/netfilter/nf_flow_table.h | --- a/include/net/netfilter/nf_flow_table.h | ||||||
| +++ b/include/net/netfilter/nf_flow_table.h | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
| @@ -90,6 +90,7 @@ struct flow_offload { | @@ -93,6 +93,7 @@ struct flow_offload { | ||||||
|  #define FLOW_OFFLOAD_PATH_ETHERNET	BIT(0) |  #define FLOW_OFFLOAD_PATH_ETHERNET	BIT(0) | ||||||
|  #define FLOW_OFFLOAD_PATH_VLAN		BIT(1) |  #define FLOW_OFFLOAD_PATH_VLAN		BIT(1) | ||||||
|  #define FLOW_OFFLOAD_PATH_PPPOE		BIT(2) |  #define FLOW_OFFLOAD_PATH_PPPOE		BIT(2) | ||||||
| @@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  struct flow_offload_hw_path { |  struct flow_offload_hw_path { | ||||||
|  	struct net_device *dev; |  	struct net_device *dev; | ||||||
| @@ -100,6 +101,7 @@ struct flow_offload_hw_path { | @@ -103,6 +104,7 @@ struct flow_offload_hw_path { | ||||||
|  	u16 vlan_proto; |  	u16 vlan_proto; | ||||||
|  	u16 vlan_id; |  	u16 vlan_id; | ||||||
|  	u16 pppoe_sid; |  	u16 pppoe_sid; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user