diff mbox series

[RFC,net-next,1/4] flow_dissector: Add PPPoE dissectors

Message ID 20220624134134.13605-2-marcin.szycik@linux.intel.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series ice: PPPoE offload support | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5647 this patch: 5647
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 1211 this patch: 1211
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 5796 this patch: 5796
netdev/checkpatch warning WARNING: line length of 87 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 7 this patch: 7
netdev/source_inline success Was 0 now: 0

Commit Message

Marcin Szycik June 24, 2022, 1:41 p.m. UTC
From: Wojciech Drewek <wojciech.drewek@intel.com>

Allow to dissect PPPoE specific fields which are:
- session ID (16 bits)
- ppp protocol (16 bits)

The goal is to make the following TC command possible:

  # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \
      flower \
        pppoe_sid 12 \
        ppp_proto ip \
      action drop

Note that only PPPoE Session is supported.

Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
---
 include/net/flow_dissector.h | 11 ++++++++
 net/core/flow_dissector.c    | 51 +++++++++++++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 6 deletions(-)

Comments

Alexander Lobakin June 24, 2022, 3:01 p.m. UTC | #1
From: Marcin Szycik <marcin.szycik@linux.intel.com>
Date: Fri, 24 Jun 2022 15:41:31 +0200

> From: Wojciech Drewek <wojciech.drewek@intel.com>
> 
> Allow to dissect PPPoE specific fields which are:
> - session ID (16 bits)
> - ppp protocol (16 bits)
> 
> The goal is to make the following TC command possible:
> 
>   # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \
>       flower \
>         pppoe_sid 12 \
>         ppp_proto ip \
>       action drop
> 
> Note that only PPPoE Session is supported.
> 
> Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
> ---
>  include/net/flow_dissector.h | 11 ++++++++
>  net/core/flow_dissector.c    | 51 +++++++++++++++++++++++++++++++-----
>  2 files changed, 56 insertions(+), 6 deletions(-)
> 
> diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> index a4c6057c7097..8ff40c7c3f1c 100644
> --- a/include/net/flow_dissector.h
> +++ b/include/net/flow_dissector.h
> @@ -261,6 +261,16 @@ struct flow_dissector_key_num_of_vlans {
>  	u8 num_of_vlans;
>  };
>  
> +/**
> + * struct flow_dissector_key_pppoe:
> + * @session_id: pppoe session id
> + * @ppp_proto: ppp protocol
> + */
> +struct flow_dissector_key_pppoe {
> +	u16 session_id;
> +	__be16 ppp_proto;
> +};
> +
>  enum flow_dissector_key_id {
>  	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
>  	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> @@ -291,6 +301,7 @@ enum flow_dissector_key_id {
>  	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
>  	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
>  	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
> +	FLOW_DISSECTOR_KEY_PPPOE,  /* struct flow_dissector_key_pppoe */
>  
>  	FLOW_DISSECTOR_KEY_MAX,
>  };
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 6aee04f75e3e..41933905f90b 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -895,6 +895,35 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
>  	return result == BPF_OK;
>  }
>  
> +static bool is_ppp_proto_supported(__be16 proto)
> +{
> +	switch (proto) {
> +	case htons(PPP_AT):
> +	case htons(PPP_IPX):
> +	case htons(PPP_VJC_COMP):
> +	case htons(PPP_VJC_UNCOMP):
> +	case htons(PPP_MP):
> +	case htons(PPP_COMPFRAG):
> +	case htons(PPP_COMP):
> +	case htons(PPP_MPLS_UC):
> +	case htons(PPP_MPLS_MC):
> +	case htons(PPP_IPCP):
> +	case htons(PPP_ATCP):
> +	case htons(PPP_IPXCP):
> +	case htons(PPP_IPV6CP):
> +	case htons(PPP_CCPFRAG):
> +	case htons(PPP_MPLSCP):
> +	case htons(PPP_LCP):
> +	case htons(PPP_PAP):
> +	case htons(PPP_LQR):
> +	case htons(PPP_CHAP):
> +	case htons(PPP_CBCP):
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>  /**
>   * __skb_flow_dissect - extract the flow_keys struct and return it
>   * @net: associated network namespace, derived from @skb if NULL
> @@ -1221,19 +1250,29 @@ bool __skb_flow_dissect(const struct net *net,
>  		}
>  
>  		nhoff += PPPOE_SES_HLEN;
> -		switch (hdr->proto) {
> -		case htons(PPP_IP):
> +		if (hdr->proto == htons(PPP_IP)) {
>  			proto = htons(ETH_P_IP);
>  			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> -			break;
> -		case htons(PPP_IPV6):
> +		} else if (hdr->proto == htons(PPP_IPV6)) {
>  			proto = htons(ETH_P_IPV6);
>  			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> -			break;
> -		default:

Oh, sorry for missing this previously. This switch -> if-else
conversion looks redundant.
You can add `if (is_ppp_proto_supported()) GOOD; else BAD` to the
`default` label without modifying the rest of code (to skip the
actual dissecting block you can add a condition there that @fdret
must not equal BAD).

> +		} else if (is_ppp_proto_supported(hdr->proto)) {
> +			fdret = FLOW_DISSECT_RET_OUT_GOOD;
> +		} else {
>  			fdret = FLOW_DISSECT_RET_OUT_BAD;
>  			break;
>  		}
> +
> +		if (dissector_uses_key(flow_dissector,
> +				       FLOW_DISSECTOR_KEY_PPPOE)) {
> +			struct flow_dissector_key_pppoe *key_pppoe;
> +
> +			key_pppoe = skb_flow_dissector_target(flow_dissector,
> +							      FLOW_DISSECTOR_KEY_PPPOE,
> +							      target_container);
> +			key_pppoe->session_id = ntohs(hdr->hdr.sid);
> +			key_pppoe->ppp_proto = hdr->proto;
> +		}
>  		break;
>  	}
>  	case htons(ETH_P_TIPC): {
> -- 
> 2.35.1

Thanks,
Olek
Baowen Zheng June 26, 2022, 7:20 a.m. UTC | #2
On Friday, June 24, 2022 9:42 PM, Marcin Szycik wrote:

>Allow to dissect PPPoE specific fields which are:
>- session ID (16 bits)
>- ppp protocol (16 bits)
>
>The goal is to make the following TC command possible:
>
>  # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \
>      flower \
>        pppoe_sid 12 \
>        ppp_proto ip \
>      action drop
>
>Note that only PPPoE Session is supported.
>
>Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
>---
> include/net/flow_dissector.h | 11 ++++++++
> net/core/flow_dissector.c    | 51 +++++++++++++++++++++++++++++++-----
> 2 files changed, 56 insertions(+), 6 deletions(-)
>
>diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index
>a4c6057c7097..8ff40c7c3f1c 100644
>--- a/include/net/flow_dissector.h
>+++ b/include/net/flow_dissector.h
>@@ -261,6 +261,16 @@ struct flow_dissector_key_num_of_vlans {
> 	u8 num_of_vlans;
> };
>
[..]
>+static bool is_ppp_proto_supported(__be16 proto) {
>+	switch (proto) {
>+	case htons(PPP_AT):
>+	case htons(PPP_IPX):
>+	case htons(PPP_VJC_COMP):
>+	case htons(PPP_VJC_UNCOMP):
>+	case htons(PPP_MP):
>+	case htons(PPP_COMPFRAG):
>+	case htons(PPP_COMP):
>+	case htons(PPP_MPLS_UC):
>+	case htons(PPP_MPLS_MC):
>+	case htons(PPP_IPCP):
>+	case htons(PPP_ATCP):
>+	case htons(PPP_IPXCP):
>+	case htons(PPP_IPV6CP):
>+	case htons(PPP_CCPFRAG):
>+	case htons(PPP_MPLSCP):
>+	case htons(PPP_LCP):
>+	case htons(PPP_PAP):
>+	case htons(PPP_LQR):
>+	case htons(PPP_CHAP):
>+	case htons(PPP_CBCP):
>+		return true;
>+	default:
>+		return false;
>+	}
>+}
>+
Just a suggestion, for the above code segment, will it be more clean to change as the format:
	switch (ntohs(proto)) {
	case PPP_AT:
	case PPP_IPX:
	case PPP_VJC_COMP:
then you will not need to call function of htons repeatedly.
> /**
>  * __skb_flow_dissect - extract the flow_keys struct and return it
>  * @net: associated network namespace, derived from @skb if NULL @@ -
>1221,19 +1250,29 @@ bool __skb_flow_dissect(const struct net *net,
> 		}
>
> 		nhoff += PPPOE_SES_HLEN;
>-		switch (hdr->proto) {
>-		case htons(PPP_IP):
>+		if (hdr->proto == htons(PPP_IP)) {
> 			proto = htons(ETH_P_IP);
> 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
>-			break;
>-		case htons(PPP_IPV6):
>+		} else if (hdr->proto == htons(PPP_IPV6)) {
> 			proto = htons(ETH_P_IPV6);
> 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
>-			break;
>-		default:
>+		} else if (is_ppp_proto_supported(hdr->proto)) {
>+			fdret = FLOW_DISSECT_RET_OUT_GOOD;
>+		} else {
> 			fdret = FLOW_DISSECT_RET_OUT_BAD;
> 			break;
> 		}
>+
>+		if (dissector_uses_key(flow_dissector,
>+				       FLOW_DISSECTOR_KEY_PPPOE)) {
>+			struct flow_dissector_key_pppoe *key_pppoe;
>+
>+			key_pppoe =
>skb_flow_dissector_target(flow_dissector,
>+
>FLOW_DISSECTOR_KEY_PPPOE,
>+							      target_container);
>+			key_pppoe->session_id = ntohs(hdr->hdr.sid);
>+			key_pppoe->ppp_proto = hdr->proto;
>+		}
> 		break;
> 	}
> 	case htons(ETH_P_TIPC): {
>--
>2.35.1
Wojciech Drewek June 27, 2022, 11:33 a.m. UTC | #3
> -----Original Message-----
> From: Lobakin, Alexandr <alexandr.lobakin@intel.com>
> Sent: piątek, 24 czerwca 2022 17:01
> To: Marcin Szycik <marcin.szycik@linux.intel.com>
> Cc: Lobakin, Alexandr <alexandr.lobakin@intel.com>; netdev@vger.kernel.org; Nguyen, Anthony L <anthony.l.nguyen@intel.com>;
> davem@davemloft.net; xiyou.wangcong@gmail.com; Brandeburg, Jesse <jesse.brandeburg@intel.com>; gustavoars@kernel.org;
> baowen.zheng@corigine.com; boris.sukholitko@broadcom.com; elic@nvidia.com; edumazet@google.com; kuba@kernel.org;
> jhs@mojatatu.com; jiri@resnulli.us; kurt@linutronix.de; pablo@netfilter.org; pabeni@redhat.com; paulb@nvidia.com;
> simon.horman@corigine.com; komachi.yoshiki@gmail.com; zhangkaiheb@126.com; intel-wired-lan@lists.osuosl.org;
> michal.swiatkowski@linux.intel.com; Drewek, Wojciech <wojciech.drewek@intel.com>
> Subject: Re: [RFC PATCH net-next 1/4] flow_dissector: Add PPPoE dissectors
> 
> From: Marcin Szycik <marcin.szycik@linux.intel.com>
> Date: Fri, 24 Jun 2022 15:41:31 +0200
> 
> > From: Wojciech Drewek <wojciech.drewek@intel.com>
> >
> > Allow to dissect PPPoE specific fields which are:
> > - session ID (16 bits)
> > - ppp protocol (16 bits)
> >
> > The goal is to make the following TC command possible:
> >
> >   # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \
> >       flower \
> >         pppoe_sid 12 \
> >         ppp_proto ip \
> >       action drop
> >
> > Note that only PPPoE Session is supported.
> >
> > Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
> > ---
> >  include/net/flow_dissector.h | 11 ++++++++
> >  net/core/flow_dissector.c    | 51 +++++++++++++++++++++++++++++++-----
> >  2 files changed, 56 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
> > index a4c6057c7097..8ff40c7c3f1c 100644
> > --- a/include/net/flow_dissector.h
> > +++ b/include/net/flow_dissector.h
> > @@ -261,6 +261,16 @@ struct flow_dissector_key_num_of_vlans {
> >  	u8 num_of_vlans;
> >  };
> >
> > +/**
> > + * struct flow_dissector_key_pppoe:
> > + * @session_id: pppoe session id
> > + * @ppp_proto: ppp protocol
> > + */
> > +struct flow_dissector_key_pppoe {
> > +	u16 session_id;
> > +	__be16 ppp_proto;
> > +};
> > +
> >  enum flow_dissector_key_id {
> >  	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
> >  	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
> > @@ -291,6 +301,7 @@ enum flow_dissector_key_id {
> >  	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
> >  	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
> >  	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
> > +	FLOW_DISSECTOR_KEY_PPPOE,  /* struct flow_dissector_key_pppoe */
> >
> >  	FLOW_DISSECTOR_KEY_MAX,
> >  };
> > diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> > index 6aee04f75e3e..41933905f90b 100644
> > --- a/net/core/flow_dissector.c
> > +++ b/net/core/flow_dissector.c
> > @@ -895,6 +895,35 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
> >  	return result == BPF_OK;
> >  }
> >
> > +static bool is_ppp_proto_supported(__be16 proto)
> > +{
> > +	switch (proto) {
> > +	case htons(PPP_AT):
> > +	case htons(PPP_IPX):
> > +	case htons(PPP_VJC_COMP):
> > +	case htons(PPP_VJC_UNCOMP):
> > +	case htons(PPP_MP):
> > +	case htons(PPP_COMPFRAG):
> > +	case htons(PPP_COMP):
> > +	case htons(PPP_MPLS_UC):
> > +	case htons(PPP_MPLS_MC):
> > +	case htons(PPP_IPCP):
> > +	case htons(PPP_ATCP):
> > +	case htons(PPP_IPXCP):
> > +	case htons(PPP_IPV6CP):
> > +	case htons(PPP_CCPFRAG):
> > +	case htons(PPP_MPLSCP):
> > +	case htons(PPP_LCP):
> > +	case htons(PPP_PAP):
> > +	case htons(PPP_LQR):
> > +	case htons(PPP_CHAP):
> > +	case htons(PPP_CBCP):
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> >  /**
> >   * __skb_flow_dissect - extract the flow_keys struct and return it
> >   * @net: associated network namespace, derived from @skb if NULL
> > @@ -1221,19 +1250,29 @@ bool __skb_flow_dissect(const struct net *net,
> >  		}
> >
> >  		nhoff += PPPOE_SES_HLEN;
> > -		switch (hdr->proto) {
> > -		case htons(PPP_IP):
> > +		if (hdr->proto == htons(PPP_IP)) {
> >  			proto = htons(ETH_P_IP);
> >  			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> > -			break;
> > -		case htons(PPP_IPV6):
> > +		} else if (hdr->proto == htons(PPP_IPV6)) {
> >  			proto = htons(ETH_P_IPV6);
> >  			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> > -			break;
> > -		default:
> 
> Oh, sorry for missing this previously. This switch -> if-else
> conversion looks redundant.
> You can add `if (is_ppp_proto_supported()) GOOD; else BAD` to the
> `default` label without modifying the rest of code (to skip the
> actual dissecting block you can add a condition there that @fdret
> must not equal BAD).

I could leave switch case statement but IMHO converting to
if else statement is cleaner then adding new if after switch case
in order to skip dissecting block.

> 
> > +		} else if (is_ppp_proto_supported(hdr->proto)) {
> > +			fdret = FLOW_DISSECT_RET_OUT_GOOD;
> > +		} else {
> >  			fdret = FLOW_DISSECT_RET_OUT_BAD;
> >  			break;
> >  		}
> > +
> > +		if (dissector_uses_key(flow_dissector,
> > +				       FLOW_DISSECTOR_KEY_PPPOE)) {
> > +			struct flow_dissector_key_pppoe *key_pppoe;
> > +
> > +			key_pppoe = skb_flow_dissector_target(flow_dissector,
> > +							      FLOW_DISSECTOR_KEY_PPPOE,
> > +							      target_container);
> > +			key_pppoe->session_id = ntohs(hdr->hdr.sid);
> > +			key_pppoe->ppp_proto = hdr->proto;
> > +		}
> >  		break;
> >  	}
> >  	case htons(ETH_P_TIPC): {
> > --
> > 2.35.1
> 
> Thanks,
> Olek
Wojciech Drewek June 27, 2022, 11:36 a.m. UTC | #4
Thanks for the review!

> -----Original Message-----
> From: Baowen Zheng <baowen.zheng@corigine.com>
> Sent: niedziela, 26 czerwca 2022 09:20
> To: Marcin Szycik <marcin.szycik@linux.intel.com>; netdev@vger.kernel.org
> Cc: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; davem@davemloft.net; xiyou.wangcong@gmail.com; Brandeburg, Jesse
> <jesse.brandeburg@intel.com>; gustavoars@kernel.org; boris.sukholitko@broadcom.com; elic@nvidia.com; edumazet@google.com;
> kuba@kernel.org; jhs@mojatatu.com; jiri@resnulli.us; kurt@linutronix.de; pablo@netfilter.org; pabeni@redhat.com;
> paulb@nvidia.com; Simon Horman <simon.horman@corigine.com>; komachi.yoshiki@gmail.com; zhangkaiheb@126.com; intel-wired-
> lan@lists.osuosl.org; michal.swiatkowski@linux.intel.com; Drewek, Wojciech <wojciech.drewek@intel.com>
> Subject: RE: [RFC PATCH net-next 1/4] flow_dissector: Add PPPoE dissectors
> 
> On Friday, June 24, 2022 9:42 PM, Marcin Szycik wrote:
> 
> >Allow to dissect PPPoE specific fields which are:
> >- session ID (16 bits)
> >- ppp protocol (16 bits)
> >
> >The goal is to make the following TC command possible:
> >
> >  # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \
> >      flower \
> >        pppoe_sid 12 \
> >        ppp_proto ip \
> >      action drop
> >
> >Note that only PPPoE Session is supported.
> >
> >Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
> >---
> > include/net/flow_dissector.h | 11 ++++++++
> > net/core/flow_dissector.c    | 51 +++++++++++++++++++++++++++++++-----
> > 2 files changed, 56 insertions(+), 6 deletions(-)
> >
> >diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index
> >a4c6057c7097..8ff40c7c3f1c 100644
> >--- a/include/net/flow_dissector.h
> >+++ b/include/net/flow_dissector.h
> >@@ -261,6 +261,16 @@ struct flow_dissector_key_num_of_vlans {
> > 	u8 num_of_vlans;
> > };
> >
> [..]
> >+static bool is_ppp_proto_supported(__be16 proto) {
> >+	switch (proto) {
> >+	case htons(PPP_AT):
> >+	case htons(PPP_IPX):
> >+	case htons(PPP_VJC_COMP):
> >+	case htons(PPP_VJC_UNCOMP):
> >+	case htons(PPP_MP):
> >+	case htons(PPP_COMPFRAG):
> >+	case htons(PPP_COMP):
> >+	case htons(PPP_MPLS_UC):
> >+	case htons(PPP_MPLS_MC):
> >+	case htons(PPP_IPCP):
> >+	case htons(PPP_ATCP):
> >+	case htons(PPP_IPXCP):
> >+	case htons(PPP_IPV6CP):
> >+	case htons(PPP_CCPFRAG):
> >+	case htons(PPP_MPLSCP):
> >+	case htons(PPP_LCP):
> >+	case htons(PPP_PAP):
> >+	case htons(PPP_LQR):
> >+	case htons(PPP_CHAP):
> >+	case htons(PPP_CBCP):
> >+		return true;
> >+	default:
> >+		return false;
> >+	}
> >+}
> >+
> Just a suggestion, for the above code segment, will it be more clean to change as the format:
> 	switch (ntohs(proto)) {
> 	case PPP_AT:
> 	case PPP_IPX:
> 	case PPP_VJC_COMP:
> then you will not need to call function of htons repeatedly.

Sure, will be included in second version.

> > /**
> >  * __skb_flow_dissect - extract the flow_keys struct and return it
> >  * @net: associated network namespace, derived from @skb if NULL @@ -
> >1221,19 +1250,29 @@ bool __skb_flow_dissect(const struct net *net,
> > 		}
> >
> > 		nhoff += PPPOE_SES_HLEN;
> >-		switch (hdr->proto) {
> >-		case htons(PPP_IP):
> >+		if (hdr->proto == htons(PPP_IP)) {
> > 			proto = htons(ETH_P_IP);
> > 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> >-			break;
> >-		case htons(PPP_IPV6):
> >+		} else if (hdr->proto == htons(PPP_IPV6)) {
> > 			proto = htons(ETH_P_IPV6);
> > 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
> >-			break;
> >-		default:
> >+		} else if (is_ppp_proto_supported(hdr->proto)) {
> >+			fdret = FLOW_DISSECT_RET_OUT_GOOD;
> >+		} else {
> > 			fdret = FLOW_DISSECT_RET_OUT_BAD;
> > 			break;
> > 		}
> >+
> >+		if (dissector_uses_key(flow_dissector,
> >+				       FLOW_DISSECTOR_KEY_PPPOE)) {
> >+			struct flow_dissector_key_pppoe *key_pppoe;
> >+
> >+			key_pppoe =
> >skb_flow_dissector_target(flow_dissector,
> >+
> >FLOW_DISSECTOR_KEY_PPPOE,
> >+							      target_container);
> >+			key_pppoe->session_id = ntohs(hdr->hdr.sid);
> >+			key_pppoe->ppp_proto = hdr->proto;
> >+		}
> > 		break;
> > 	}
> > 	case htons(ETH_P_TIPC): {
> >--
> >2.35.1
diff mbox series

Patch

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index a4c6057c7097..8ff40c7c3f1c 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -261,6 +261,16 @@  struct flow_dissector_key_num_of_vlans {
 	u8 num_of_vlans;
 };
 
+/**
+ * struct flow_dissector_key_pppoe:
+ * @session_id: pppoe session id
+ * @ppp_proto: ppp protocol
+ */
+struct flow_dissector_key_pppoe {
+	u16 session_id;
+	__be16 ppp_proto;
+};
+
 enum flow_dissector_key_id {
 	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
 	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -291,6 +301,7 @@  enum flow_dissector_key_id {
 	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
 	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
 	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
+	FLOW_DISSECTOR_KEY_PPPOE,  /* struct flow_dissector_key_pppoe */
 
 	FLOW_DISSECTOR_KEY_MAX,
 };
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 6aee04f75e3e..41933905f90b 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -895,6 +895,35 @@  bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
 	return result == BPF_OK;
 }
 
+static bool is_ppp_proto_supported(__be16 proto)
+{
+	switch (proto) {
+	case htons(PPP_AT):
+	case htons(PPP_IPX):
+	case htons(PPP_VJC_COMP):
+	case htons(PPP_VJC_UNCOMP):
+	case htons(PPP_MP):
+	case htons(PPP_COMPFRAG):
+	case htons(PPP_COMP):
+	case htons(PPP_MPLS_UC):
+	case htons(PPP_MPLS_MC):
+	case htons(PPP_IPCP):
+	case htons(PPP_ATCP):
+	case htons(PPP_IPXCP):
+	case htons(PPP_IPV6CP):
+	case htons(PPP_CCPFRAG):
+	case htons(PPP_MPLSCP):
+	case htons(PPP_LCP):
+	case htons(PPP_PAP):
+	case htons(PPP_LQR):
+	case htons(PPP_CHAP):
+	case htons(PPP_CBCP):
+		return true;
+	default:
+		return false;
+	}
+}
+
 /**
  * __skb_flow_dissect - extract the flow_keys struct and return it
  * @net: associated network namespace, derived from @skb if NULL
@@ -1221,19 +1250,29 @@  bool __skb_flow_dissect(const struct net *net,
 		}
 
 		nhoff += PPPOE_SES_HLEN;
-		switch (hdr->proto) {
-		case htons(PPP_IP):
+		if (hdr->proto == htons(PPP_IP)) {
 			proto = htons(ETH_P_IP);
 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
-			break;
-		case htons(PPP_IPV6):
+		} else if (hdr->proto == htons(PPP_IPV6)) {
 			proto = htons(ETH_P_IPV6);
 			fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
-			break;
-		default:
+		} else if (is_ppp_proto_supported(hdr->proto)) {
+			fdret = FLOW_DISSECT_RET_OUT_GOOD;
+		} else {
 			fdret = FLOW_DISSECT_RET_OUT_BAD;
 			break;
 		}
+
+		if (dissector_uses_key(flow_dissector,
+				       FLOW_DISSECTOR_KEY_PPPOE)) {
+			struct flow_dissector_key_pppoe *key_pppoe;
+
+			key_pppoe = skb_flow_dissector_target(flow_dissector,
+							      FLOW_DISSECTOR_KEY_PPPOE,
+							      target_container);
+			key_pppoe->session_id = ntohs(hdr->hdr.sid);
+			key_pppoe->ppp_proto = hdr->proto;
+		}
 		break;
 	}
 	case htons(ETH_P_TIPC): {