@@ -198,7 +198,7 @@ pub enum EncOpts {
198198 Geneve ( Vec < GeneveEncOpts > ) ,
199199 Vxlan ( Vec < VxlanEncOpts > ) ,
200200 Erspan ( Vec < ErspanEncOpts > ) ,
201- // Gtp(Vec<u8 >), // TODO: I don't know what this is well enough to
201+ Gtp ( Vec < GtpEncOpts > ) , // TODO: I don't know what this is well enough to
202202 // implement it confidently.
203203 Other ( DefaultNla ) ,
204204}
@@ -209,7 +209,7 @@ impl Nla for EncOpts {
209209 Self :: Geneve ( opts) => opts. as_slice ( ) . buffer_len ( ) ,
210210 Self :: Vxlan ( opts) => opts. as_slice ( ) . buffer_len ( ) ,
211211 Self :: Erspan ( opts) => opts. as_slice ( ) . buffer_len ( ) ,
212- // Self::Gtp(v ) => v.len (),
212+ Self :: Gtp ( opts ) => opts . as_slice ( ) . buffer_len ( ) ,
213213 Self :: Other ( nla) => nla. value_len ( ) ,
214214 }
215215 }
@@ -219,7 +219,7 @@ impl Nla for EncOpts {
219219 Self :: Geneve ( _) => TCA_FLOWER_KEY_ENC_OPTS_GENEVE ,
220220 Self :: Vxlan ( _) => TCA_FLOWER_KEY_ENC_OPTS_VXLAN ,
221221 Self :: Erspan ( _) => TCA_FLOWER_KEY_ENC_OPTS_ERSPAN ,
222- // Self::Gtp(_) => TCA_FLOWER_KEY_ENC_OPTS_GTP,
222+ Self :: Gtp ( _) => TCA_FLOWER_KEY_ENC_OPTS_GTP ,
223223 Self :: Other ( nla) => nla. kind ( ) ,
224224 }
225225 }
@@ -229,7 +229,7 @@ impl Nla for EncOpts {
229229 Self :: Geneve ( opts) => opts. as_slice ( ) . emit ( buffer) ,
230230 Self :: Vxlan ( opts) => opts. as_slice ( ) . emit ( buffer) ,
231231 Self :: Erspan ( opts) => opts. as_slice ( ) . emit ( buffer) ,
232- // Self::Gtp(v ) => buffer.copy_from_slice(v ),
232+ Self :: Gtp ( opts ) => opts . as_slice ( ) . emit ( buffer ) ,
233233 Self :: Other ( nla) => nla. emit_value ( buffer) ,
234234 }
235235 }
@@ -2612,3 +2612,64 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for CfmAttribute {
26122612 } )
26132613 }
26142614}
2615+
2616+ const TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE : u16 = 1 ; /* u8 */
2617+ const TCA_FLOWER_KEY_ENC_OPT_GTP_QFI : u16 = 2 ; /* u8 */
2618+
2619+ /// I don't have any real experience with GTP.
2620+ /// It looks like the [spec for GTP `PduType`][1] is available
2621+ /// but the number of codes is fairly large, and I am not sure
2622+ /// more than `u8` is justified.
2623+ /// I can implement all of those codes as an enum if needed.
2624+ ///
2625+ /// [1]: https://www.etsi.org/deliver/etsi_ts/129000_129099/129060/12.06.00_60/ts_129060v120600p.pdf#page=22
2626+ #[ derive( Debug , PartialEq , Eq , Clone ) ]
2627+ #[ non_exhaustive]
2628+ pub enum GtpEncOpts {
2629+ PduType ( u8 ) ,
2630+ Qfi ( u8 ) ,
2631+ Other ( DefaultNla ) ,
2632+ }
2633+
2634+ impl Nla for GtpEncOpts {
2635+ fn value_len ( & self ) -> usize {
2636+ 1
2637+ }
2638+
2639+ fn kind ( & self ) -> u16 {
2640+ match self {
2641+ GtpEncOpts :: PduType ( _) => TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE ,
2642+ GtpEncOpts :: Qfi ( _) => TCA_FLOWER_KEY_ENC_OPT_GTP_QFI ,
2643+ GtpEncOpts :: Other ( nla) => nla. kind ( ) ,
2644+ }
2645+ }
2646+
2647+ fn emit_value ( & self , buffer : & mut [ u8 ] ) {
2648+ match self {
2649+ GtpEncOpts :: PduType ( pdu_type) => {
2650+ buffer[ 0 ] = * pdu_type;
2651+ }
2652+ GtpEncOpts :: Qfi ( qfi) => {
2653+ buffer[ 0 ] = * qfi;
2654+ }
2655+ GtpEncOpts :: Other ( nla) => nla. emit_value ( buffer) ,
2656+ }
2657+ }
2658+ }
2659+
2660+ impl < ' a , T : AsRef < [ u8 ] > + ?Sized > Parseable < NlaBuffer < & ' a T > > for GtpEncOpts {
2661+ fn parse ( buf : & NlaBuffer < & ' a T > ) -> Result < Self , DecodeError > {
2662+ let payload = buf. value ( ) ;
2663+ Ok ( match buf. kind ( ) {
2664+ TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE => {
2665+ GtpEncOpts :: PduType ( parse_u8 ( payload) ?)
2666+ }
2667+ TCA_FLOWER_KEY_ENC_OPT_GTP_QFI => {
2668+ GtpEncOpts :: Qfi ( parse_u8 ( payload) ?)
2669+ }
2670+ _ => GtpEncOpts :: Other (
2671+ DefaultNla :: parse ( buf) . context ( "failed to parse gtp nla" ) ?,
2672+ ) ,
2673+ } )
2674+ }
2675+ }
0 commit comments