4141#include  <net/addrconf.h> 
4242#include  <net/xfrm.h> 
4343#include  <net/net_namespace.h> 
44+ #include  <net/dst_metadata.h> 
4445#include  <net/netns/generic.h> 
4546#include  <linux/etherdevice.h> 
4647
@@ -56,6 +57,7 @@ static const struct net_device_ops xfrmi_netdev_ops;
5657struct  xfrmi_net  {
5758	/* lists for storing interfaces in use */ 
5859	struct  xfrm_if  __rcu  * xfrmi [XFRMI_HASH_SIZE ];
60+ 	struct  xfrm_if  __rcu  * collect_md_xfrmi ;
5961};
6062
6163#define  for_each_xfrmi_rcu (start , xi ) \
@@ -77,17 +79,23 @@ static struct xfrm_if *xfrmi_lookup(struct net *net, struct xfrm_state *x)
7779			return  xi ;
7880	}
7981
82+ 	xi  =  rcu_dereference (xfrmn -> collect_md_xfrmi );
83+ 	if  (xi  &&  (xi -> dev -> flags  &  IFF_UP ))
84+ 		return  xi ;
85+ 
8086	return  NULL ;
8187}
8288
83- static  struct  xfrm_if  * xfrmi_decode_session (struct  sk_buff  * skb ,
84- 					    unsigned short  family )
89+ static  bool  xfrmi_decode_session (struct  sk_buff  * skb ,
90+ 				 unsigned short  family ,
91+ 				 struct  xfrm_if_decode_session_result  * res )
8592{
8693	struct  net_device  * dev ;
94+ 	struct  xfrm_if  * xi ;
8795	int  ifindex  =  0 ;
8896
8997	if  (!secpath_exists (skb ) ||  !skb -> dev )
90- 		return  NULL ;
98+ 		return  false ;
9199
92100	switch  (family ) {
93101	case  AF_INET6 :
@@ -107,11 +115,18 @@ static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb,
107115	}
108116
109117	if  (!dev  ||  !(dev -> flags  &  IFF_UP ))
110- 		return  NULL ;
118+ 		return  false ;
111119	if  (dev -> netdev_ops  !=  & xfrmi_netdev_ops )
112- 		return  NULL ;
120+ 		return  false ;
113121
114- 	return  netdev_priv (dev );
122+ 	xi  =  netdev_priv (dev );
123+ 	res -> net  =  xi -> net ;
124+ 
125+ 	if  (xi -> p .collect_md )
126+ 		res -> if_id  =  xfrm_input_state (skb )-> if_id ;
127+ 	else 
128+ 		res -> if_id  =  xi -> p .if_id ;
129+ 	return  true;
115130}
116131
117132static  void  xfrmi_link (struct  xfrmi_net  * xfrmn , struct  xfrm_if  * xi )
@@ -157,7 +172,10 @@ static int xfrmi_create(struct net_device *dev)
157172	if  (err  <  0 )
158173		goto out ;
159174
160- 	xfrmi_link (xfrmn , xi );
175+ 	if  (xi -> p .collect_md )
176+ 		rcu_assign_pointer (xfrmn -> collect_md_xfrmi , xi );
177+ 	else 
178+ 		xfrmi_link (xfrmn , xi );
161179
162180	return  0 ;
163181
@@ -185,7 +203,10 @@ static void xfrmi_dev_uninit(struct net_device *dev)
185203	struct  xfrm_if  * xi  =  netdev_priv (dev );
186204	struct  xfrmi_net  * xfrmn  =  net_generic (xi -> net , xfrmi_net_id );
187205
188- 	xfrmi_unlink (xfrmn , xi );
206+ 	if  (xi -> p .collect_md )
207+ 		RCU_INIT_POINTER (xfrmn -> collect_md_xfrmi , NULL );
208+ 	else 
209+ 		xfrmi_unlink (xfrmn , xi );
189210}
190211
191212static  void  xfrmi_scrub_packet (struct  sk_buff  * skb , bool  xnet )
@@ -214,6 +235,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
214235	struct  xfrm_state  * x ;
215236	struct  xfrm_if  * xi ;
216237	bool  xnet ;
238+ 	int  link ;
217239
218240	if  (err  &&  !secpath_exists (skb ))
219241		return  0 ;
@@ -224,6 +246,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
224246	if  (!xi )
225247		return  1 ;
226248
249+ 	link  =  skb -> dev -> ifindex ;
227250	dev  =  xi -> dev ;
228251	skb -> dev  =  dev ;
229252
@@ -254,6 +277,17 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
254277	}
255278
256279	xfrmi_scrub_packet (skb , xnet );
280+ 	if  (xi -> p .collect_md ) {
281+ 		struct  metadata_dst  * md_dst ;
282+ 
283+ 		md_dst  =  metadata_dst_alloc (0 , METADATA_XFRM , GFP_ATOMIC );
284+ 		if  (!md_dst )
285+ 			return  - ENOMEM ;
286+ 
287+ 		md_dst -> u .xfrm_info .if_id  =  x -> if_id ;
288+ 		md_dst -> u .xfrm_info .link  =  link ;
289+ 		skb_dst_set (skb , (struct  dst_entry  * )md_dst );
290+ 	}
257291	dev_sw_netstats_rx_add (dev , skb -> len );
258292
259293	return  0 ;
@@ -269,10 +303,23 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
269303	struct  net_device  * tdev ;
270304	struct  xfrm_state  * x ;
271305	int  err  =  -1 ;
306+ 	u32  if_id ;
272307	int  mtu ;
273308
309+ 	if  (xi -> p .collect_md ) {
310+ 		struct  xfrm_md_info  * md_info  =  skb_xfrm_md_info (skb );
311+ 
312+ 		if  (unlikely (!md_info ))
313+ 			return  - EINVAL ;
314+ 
315+ 		if_id  =  md_info -> if_id ;
316+ 		fl -> flowi_oif  =  md_info -> link ;
317+ 	} else  {
318+ 		if_id  =  xi -> p .if_id ;
319+ 	}
320+ 
274321	dst_hold (dst );
275- 	dst  =  xfrm_lookup_with_ifid (xi -> net , dst , fl , NULL , 0 , xi -> p . if_id );
322+ 	dst  =  xfrm_lookup_with_ifid (xi -> net , dst , fl , NULL , 0 , if_id );
276323	if  (IS_ERR (dst )) {
277324		err  =  PTR_ERR (dst );
278325		dst  =  NULL ;
@@ -283,7 +330,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
283330	if  (!x )
284331		goto tx_err_link_failure ;
285332
286- 	if  (x -> if_id  !=  xi -> p . if_id )
333+ 	if  (x -> if_id  !=  if_id )
287334		goto tx_err_link_failure ;
288335
289336	tdev  =  dst -> dev ;
@@ -633,6 +680,9 @@ static void xfrmi_netlink_parms(struct nlattr *data[],
633680
634681	if  (data [IFLA_XFRM_IF_ID ])
635682		parms -> if_id  =  nla_get_u32 (data [IFLA_XFRM_IF_ID ]);
683+ 
684+ 	if  (data [IFLA_XFRM_COLLECT_METADATA ])
685+ 		parms -> collect_md  =  true;
636686}
637687
638688static  int  xfrmi_newlink (struct  net  * src_net , struct  net_device  * dev ,
@@ -645,14 +695,27 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
645695	int  err ;
646696
647697	xfrmi_netlink_parms (data , & p );
648- 	if  (!p .if_id ) {
649- 		NL_SET_ERR_MSG (extack , "if_id must be non zero" );
650- 		return  - EINVAL ;
651- 	}
698+ 	if  (p .collect_md ) {
699+ 		struct  xfrmi_net  * xfrmn  =  net_generic (net , xfrmi_net_id );
652700
653- 	xi  =  xfrmi_locate (net , & p );
654- 	if  (xi )
655- 		return  - EEXIST ;
701+ 		if  (p .link  ||  p .if_id ) {
702+ 			NL_SET_ERR_MSG (extack , "link and if_id must be zero" );
703+ 			return  - EINVAL ;
704+ 		}
705+ 
706+ 		if  (rtnl_dereference (xfrmn -> collect_md_xfrmi ))
707+ 			return  - EEXIST ;
708+ 
709+ 	} else  {
710+ 		if  (!p .if_id ) {
711+ 			NL_SET_ERR_MSG (extack , "if_id must be non zero" );
712+ 			return  - EINVAL ;
713+ 		}
714+ 
715+ 		xi  =  xfrmi_locate (net , & p );
716+ 		if  (xi )
717+ 			return  - EEXIST ;
718+ 	}
656719
657720	xi  =  netdev_priv (dev );
658721	xi -> p  =  p ;
@@ -682,12 +745,22 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
682745		return  - EINVAL ;
683746	}
684747
748+ 	if  (p .collect_md ) {
749+ 		NL_SET_ERR_MSG (extack , "collect_md can't be changed" );
750+ 		return  - EINVAL ;
751+ 	}
752+ 
685753	xi  =  xfrmi_locate (net , & p );
686754	if  (!xi ) {
687755		xi  =  netdev_priv (dev );
688756	} else  {
689757		if  (xi -> dev  !=  dev )
690758			return  - EEXIST ;
759+ 		if  (xi -> p .collect_md ) {
760+ 			NL_SET_ERR_MSG (extack ,
761+ 				       "device can't be changed to collect_md" );
762+ 			return  - EINVAL ;
763+ 		}
691764	}
692765
693766	return  xfrmi_update (xi , & p );
@@ -700,6 +773,8 @@ static size_t xfrmi_get_size(const struct net_device *dev)
700773		nla_total_size (4 ) + 
701774		/* IFLA_XFRM_IF_ID */ 
702775		nla_total_size (4 ) + 
776+ 		/* IFLA_XFRM_COLLECT_METADATA */ 
777+ 		nla_total_size (0 ) + 
703778		0 ;
704779}
705780
@@ -709,7 +784,8 @@ static int xfrmi_fill_info(struct sk_buff *skb, const struct net_device *dev)
709784	struct  xfrm_if_parms  * parm  =  & xi -> p ;
710785
711786	if  (nla_put_u32 (skb , IFLA_XFRM_LINK , parm -> link ) || 
712- 	    nla_put_u32 (skb , IFLA_XFRM_IF_ID , parm -> if_id ))
787+ 	    nla_put_u32 (skb , IFLA_XFRM_IF_ID , parm -> if_id ) || 
788+ 	    (xi -> p .collect_md  &&  nla_put_flag (skb , IFLA_XFRM_COLLECT_METADATA )))
713789		goto nla_put_failure ;
714790	return  0 ;
715791
@@ -725,8 +801,10 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
725801}
726802
727803static  const  struct  nla_policy  xfrmi_policy [IFLA_XFRM_MAX  +  1 ] =  {
728- 	[IFLA_XFRM_LINK ]	=  { .type  =  NLA_U32  },
729- 	[IFLA_XFRM_IF_ID ]	=  { .type  =  NLA_U32  },
804+ 	[IFLA_XFRM_UNSPEC ]		=  { .strict_start_type  =  IFLA_XFRM_COLLECT_METADATA  },
805+ 	[IFLA_XFRM_LINK ]		=  { .type  =  NLA_U32  },
806+ 	[IFLA_XFRM_IF_ID ]		=  { .type  =  NLA_U32  },
807+ 	[IFLA_XFRM_COLLECT_METADATA ]	=  { .type  =  NLA_FLAG  },
730808};
731809
732810static  struct  rtnl_link_ops  xfrmi_link_ops  __read_mostly  =  {
@@ -762,6 +840,9 @@ static void __net_exit xfrmi_exit_batch_net(struct list_head *net_exit_list)
762840			     xip  =  & xi -> next )
763841				unregister_netdevice_queue (xi -> dev , & list );
764842		}
843+ 		xi  =  rtnl_dereference (xfrmn -> collect_md_xfrmi );
844+ 		if  (xi )
845+ 			unregister_netdevice_queue (xi -> dev , & list );
765846	}
766847	unregister_netdevice_many (& list );
767848	rtnl_unlock ();
0 commit comments