@@ -299,6 +299,11 @@ static bool mpls_egress(struct net *net, struct mpls_route *rt,
299299 success = true;
300300 break ;
301301 }
302+ case MPT_VPLS :
303+ /* nothing to do here, no TTL in Ethernet
304+ * (and we shouldn't mess with the TTL in inner IP packets,
305+ * pseudowires are supposed to be transparent) */
306+ break ;
302307 case MPT_UNSPEC :
303308 /* Should have decided which protocol it is by now */
304309 break ;
@@ -349,6 +354,8 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
349354 goto drop ;
350355 }
351356
357+ if (rt -> rt_payload_type == MPT_VPLS )
358+ return vpls_rcv (skb , dev , pt , rt , hdr , orig_dev );
352359
353360 /* Pop the label */
354361 skb_pull (skb , sizeof (* hdr ));
@@ -469,6 +476,7 @@ static const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = {
469476struct mpls_route_config {
470477 u32 rc_protocol ;
471478 u32 rc_ifindex ;
479+ u32 rc_vpls_ifindex ;
472480 u8 rc_via_table ;
473481 u8 rc_via_alen ;
474482 u8 rc_via [MAX_VIA_ALEN ];
@@ -541,6 +549,8 @@ static void mpls_route_update(struct net *net, unsigned index,
541549 rt = rtnl_dereference (platform_label [index ]);
542550 rcu_assign_pointer (platform_label [index ], new );
543551
552+ vpls_label_update (index , rt , new );
553+
544554 mpls_notify_route (net , index , rt , new , info );
545555
546556 /* If we removed a route free it now */
@@ -942,6 +952,7 @@ static int mpls_route_add(struct mpls_route_config *cfg,
942952 struct mpls_route __rcu * * platform_label ;
943953 struct net * net = cfg -> rc_nlinfo .nl_net ;
944954 struct mpls_route * rt , * old ;
955+ struct net_device * vpls_dev = NULL ;
945956 int err = - EINVAL ;
946957 u8 max_via_alen ;
947958 unsigned index ;
@@ -996,6 +1007,24 @@ static int mpls_route_add(struct mpls_route_config *cfg,
9961007 goto errout ;
9971008 }
9981009
1010+ if (cfg -> rc_vpls_ifindex ) {
1011+ vpls_dev = dev_get_by_index (net , cfg -> rc_vpls_ifindex );
1012+ if (!vpls_dev ) {
1013+ err = - ENODEV ;
1014+ NL_SET_ERR_MSG (extack , "Invalid VPLS ifindex" );
1015+ goto errout ;
1016+ }
1017+ /* we're under RTNL; and we'll drop routes when we're
1018+ * notified the device is going away. */
1019+ dev_put (vpls_dev );
1020+
1021+ if (!is_vpls_dev (vpls_dev )) {
1022+ err = - ENODEV ;
1023+ NL_SET_ERR_MSG (extack , "Not a VPLS device" );
1024+ goto errout ;
1025+ }
1026+ }
1027+
9991028 err = - ENOMEM ;
10001029 rt = mpls_rt_alloc (nhs , max_via_alen , max_labels );
10011030 if (IS_ERR (rt )) {
@@ -1006,6 +1035,7 @@ static int mpls_route_add(struct mpls_route_config *cfg,
10061035 rt -> rt_protocol = cfg -> rc_protocol ;
10071036 rt -> rt_payload_type = cfg -> rc_payload_type ;
10081037 rt -> rt_ttl_propagate = cfg -> rc_ttl_propagate ;
1038+ rt -> rt_vpls_dev = vpls_dev ;
10091039
10101040 if (cfg -> rc_mp )
10111041 err = mpls_nh_build_multi (cfg , rt , max_labels , extack );
@@ -1430,6 +1460,14 @@ static void mpls_ifdown(struct net_device *dev, int event)
14301460 if (!rt )
14311461 continue ;
14321462
1463+ if (rt -> rt_vpls_dev == dev ) {
1464+ switch (event ) {
1465+ case NETDEV_UNREGISTER :
1466+ mpls_route_update (net , index , NULL , NULL );
1467+ continue ;
1468+ }
1469+ }
1470+
14331471 alive = 0 ;
14341472 deleted = 0 ;
14351473 change_nexthops (rt ) {
@@ -1777,6 +1815,10 @@ static int rtm_to_route_config(struct sk_buff *skb,
17771815 case RTA_OIF :
17781816 cfg -> rc_ifindex = nla_get_u32 (nla );
17791817 break ;
1818+ case RTA_VPLS_IF :
1819+ cfg -> rc_vpls_ifindex = nla_get_u32 (nla );
1820+ cfg -> rc_payload_type = MPT_VPLS ;
1821+ break ;
17801822 case RTA_NEWDST :
17811823 if (nla_get_labels (nla , MAX_NEW_LABELS ,
17821824 & cfg -> rc_output_labels ,
@@ -1911,6 +1953,11 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event,
19111953 ttl_propagate ))
19121954 goto nla_put_failure ;
19131955 }
1956+
1957+ if (rt -> rt_vpls_dev )
1958+ if (nla_put_u32 (skb , RTA_VPLS_IF , rt -> rt_vpls_dev -> ifindex ))
1959+ goto nla_put_failure ;
1960+
19141961 if (rt -> rt_nhn == 1 ) {
19151962 const struct mpls_nh * nh = rt -> rt_nh ;
19161963
@@ -2220,6 +2267,10 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
22202267 if (nla_put_labels (skb , RTA_DST , 1 , & in_label ))
22212268 goto nla_put_failure ;
22222269
2270+ if (rt -> rt_vpls_dev )
2271+ if (nla_put_u32 (skb , RTA_VPLS_IF , rt -> rt_vpls_dev -> ifindex ))
2272+ goto nla_put_failure ;
2273+
22232274 if (nh -> nh_labels &&
22242275 nla_put_labels (skb , RTA_NEWDST , nh -> nh_labels ,
22252276 nh -> nh_label ))
@@ -2491,6 +2542,8 @@ static int __init mpls_init(void)
24912542
24922543 rtnl_af_register (& mpls_af_ops );
24932544
2545+ vpls_init ();
2546+
24942547 rtnl_register (PF_MPLS , RTM_NEWROUTE , mpls_rtm_newroute , NULL , 0 );
24952548 rtnl_register (PF_MPLS , RTM_DELROUTE , mpls_rtm_delroute , NULL , 0 );
24962549 rtnl_register (PF_MPLS , RTM_GETROUTE , mpls_getroute , mpls_dump_routes ,
@@ -2510,6 +2563,7 @@ module_init(mpls_init);
25102563static void __exit mpls_exit (void )
25112564{
25122565 rtnl_unregister_all (PF_MPLS );
2566+ vpls_exit ();
25132567 rtnl_af_unregister (& mpls_af_ops );
25142568 dev_remove_pack (& mpls_packet_type );
25152569 unregister_netdevice_notifier (& mpls_dev_notifier );
0 commit comments