1919#include <linux/module.h>
2020#include <net/dst_metadata.h>
2121#include <net/ip_tunnels.h>
22+ #include <linux/lwtunnel.h>
2223
2324#include "internal.h"
2425
@@ -353,6 +354,51 @@ static void vpls_dev_free(struct net_device *dev)
353354 free_netdev (dev );
354355}
355356
357+ static const struct nla_policy vpls_meta_policy [LWT_PSEUDOWIRE_MAX + 1 ] = {
358+ [LWT_PSEUDOWIRE_LOCAL_LABEL ] = { .type = NLA_U32 },
359+ };
360+
361+ static int vpls_fill_metadst (struct sk_buff * skb , struct metadata_dst * md_dst )
362+ {
363+ struct vpls_info * vi ;
364+ if (md_dst -> type != METADATA_VPLS )
365+ return 0 ;
366+
367+ vi = & md_dst -> u .vpls_info ;
368+ if (nla_put_u32 (skb , LWT_PSEUDOWIRE_LOCAL_LABEL , vi -> pw_label ))
369+ return - ENOMEM ;
370+ return LWTUNNEL_ENCAP_PSEUDOWIRE ;
371+ }
372+
373+ static int vpls_build_metadst (struct net_device * dev , struct nlattr * meta ,
374+ struct metadata_dst * * dst ,
375+ struct netlink_ext_ack * extack )
376+ {
377+ struct nlattr * tb [LWT_PSEUDOWIRE_MAX + 1 ];
378+ struct metadata_dst * rv ;
379+ int err ;
380+ unsigned wire ;
381+
382+ err = nla_parse_nested (tb , LWT_PSEUDOWIRE_MAX , meta ,
383+ vpls_meta_policy , extack );
384+ if (err < 0 )
385+ return err ;
386+
387+ if (!tb [LWT_PSEUDOWIRE_LOCAL_LABEL ])
388+ return - EINVAL ;
389+ wire = nla_get_u32 (tb [LWT_PSEUDOWIRE_LOCAL_LABEL ]);
390+ if (wire < MPLS_LABEL_FIRST_UNRESERVED )
391+ return - EINVAL ;
392+
393+ rv = vpls_rx_dst ();
394+ if (!rv )
395+ return - ENOMEM ;
396+ rv -> u .vpls_info .pw_label = wire ;
397+
398+ * dst = rv ;
399+ return 0 ;
400+ }
401+
356402static const struct net_device_ops vpls_netdev_ops = {
357403 .ndo_init = vpls_dev_init ,
358404 .ndo_open = vpls_open ,
@@ -363,6 +409,8 @@ static const struct net_device_ops vpls_netdev_ops = {
363409 .ndo_set_rx_mode = vpls_set_multicast_list ,
364410 .ndo_set_mac_address = eth_mac_addr ,
365411 .ndo_features_check = passthru_features_check ,
412+ .ndo_metadst_fill = vpls_fill_metadst ,
413+ .ndo_metadst_build = vpls_build_metadst ,
366414};
367415
368416int is_vpls_dev (struct net_device * dev )
0 commit comments