Skip to content

Commit 6c58eed

Browse files
committed
vpls: make dst metadata accessible on netlink
Signed-off-by: David Lamparter <equinox@diac24.net>
1 parent 0b29a8d commit 6c58eed

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

include/uapi/linux/lwtunnel.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum lwtunnel_encap_types {
1212
LWTUNNEL_ENCAP_SEG6,
1313
LWTUNNEL_ENCAP_BPF,
1414
LWTUNNEL_ENCAP_SEG6_LOCAL,
15+
LWTUNNEL_ENCAP_PSEUDOWIRE,
1516
__LWTUNNEL_ENCAP_MAX,
1617
};
1718

@@ -67,4 +68,11 @@ enum {
6768

6869
#define LWT_BPF_MAX_HEADROOM 256
6970

71+
enum {
72+
LWT_PSEUDOWIRE_LOCAL_LABEL,
73+
__LWT_PSEUDOWIRE_MAX,
74+
};
75+
76+
#define LWT_PSEUDOWIRE_MAX (__LWT_PSEUDOWIRE_MAX - 1)
77+
7078
#endif /* _UAPI_LWTUNNEL_H_ */

net/core/lwtunnel.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
4949
case LWTUNNEL_ENCAP_IP6:
5050
case LWTUNNEL_ENCAP_IP:
5151
case LWTUNNEL_ENCAP_NONE:
52+
case LWTUNNEL_ENCAP_PSEUDOWIRE:
5253
case __LWTUNNEL_ENCAP_MAX:
5354
/* should not have got here */
5455
WARN_ON(1);

net/mpls/vpls.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
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+
356402
static 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

368416
int is_vpls_dev(struct net_device *dev)

0 commit comments

Comments
 (0)