mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2024-11-24 02:29:50 +00:00
route: Add support for MPLS encap
Add support for MPLS lwtunnel encapsulation. Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
0164d57aee
commit
760d74f99c
@ -386,6 +386,7 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/netconf.c \
|
||||
lib/route/nexthop.c \
|
||||
lib/route/nexthop_encap.c \
|
||||
lib/route/nh_encap_mpls.c \
|
||||
lib/route/pktloc.c \
|
||||
lib/route/qdisc/blackhole.c \
|
||||
lib/route/qdisc.c \
|
||||
|
@ -27,4 +27,9 @@ int nh_encap_build_msg(struct nl_msg *msg, struct rtnl_nh_encap *rtnh_encap);
|
||||
void nh_encap_dump(struct rtnl_nh_encap *rtnh_encap, struct nl_dump_params *dp);
|
||||
|
||||
int nh_encap_compare(struct rtnl_nh_encap *a, struct rtnl_nh_encap *b);
|
||||
|
||||
/*
|
||||
* MPLS encap
|
||||
*/
|
||||
extern struct nh_encap_ops mpls_encap_ops;
|
||||
#endif
|
||||
|
@ -64,6 +64,12 @@ extern struct nl_addr * rtnl_route_nh_get_via(struct rtnl_nexthop *);
|
||||
extern char * rtnl_route_nh_flags2str(int, char *, size_t);
|
||||
extern int rtnl_route_nh_str2flags(const char *);
|
||||
|
||||
/*
|
||||
* nexthop encapsulations
|
||||
*/
|
||||
extern int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
|
||||
struct nl_addr *addr,
|
||||
uint8_t ttl);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -9,7 +9,7 @@ static struct lwtunnel_encap_type {
|
||||
struct nh_encap_ops *ops;
|
||||
} lwtunnel_encap_types[__LWTUNNEL_ENCAP_MAX] = {
|
||||
[LWTUNNEL_ENCAP_NONE] = { .name = "none" },
|
||||
[LWTUNNEL_ENCAP_MPLS] = { .name = "mpls" },
|
||||
[LWTUNNEL_ENCAP_MPLS] = { .name = "mpls", .ops = &mpls_encap_ops },
|
||||
[LWTUNNEL_ENCAP_IP] = { .name = "ip" },
|
||||
[LWTUNNEL_ENCAP_IP6] = { .name = "ip6" },
|
||||
[LWTUNNEL_ENCAP_ILA] = { .name = "ila" },
|
||||
|
134
lib/route/nh_encap_mpls.c
Normal file
134
lib/route/nh_encap_mpls.c
Normal file
@ -0,0 +1,134 @@
|
||||
|
||||
#include <netlink-private/netlink.h>
|
||||
#include <netlink-private/types.h>
|
||||
#include <netlink-private/route/nexthop-encap.h>
|
||||
#include <netlink/route/nexthop.h>
|
||||
#include <linux/mpls_iptunnel.h>
|
||||
#include <linux/lwtunnel.h>
|
||||
|
||||
struct mpls_iptunnel_encap {
|
||||
struct nl_addr *dst;
|
||||
uint8_t ttl;
|
||||
};
|
||||
|
||||
static void mpls_encap_dump(void *priv, struct nl_dump_params *dp)
|
||||
{
|
||||
struct mpls_iptunnel_encap *encap_info = priv;
|
||||
char buf[256];
|
||||
|
||||
nl_dump(dp, "%s ", nl_addr2str(encap_info->dst, buf, sizeof(buf)));
|
||||
|
||||
if (encap_info->ttl)
|
||||
nl_dump(dp, "ttl %u ", encap_info->ttl);
|
||||
}
|
||||
|
||||
static int mpls_encap_build_msg(struct nl_msg *msg, void *priv)
|
||||
{
|
||||
struct mpls_iptunnel_encap *encap_info = priv;
|
||||
|
||||
NLA_PUT_ADDR(msg, MPLS_IPTUNNEL_DST, encap_info->dst);
|
||||
if (encap_info->ttl)
|
||||
NLA_PUT_U8(msg, MPLS_IPTUNNEL_TTL, encap_info->ttl);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -NLE_MSGSIZE;
|
||||
}
|
||||
|
||||
static void mpls_encap_destructor(void *priv)
|
||||
{
|
||||
struct mpls_iptunnel_encap *encap_info = priv;
|
||||
|
||||
nl_addr_put(encap_info->dst);
|
||||
}
|
||||
|
||||
static struct nla_policy mpls_encap_policy[MPLS_IPTUNNEL_MAX + 1] = {
|
||||
[MPLS_IPTUNNEL_DST] = { .type = NLA_U32 },
|
||||
[MPLS_IPTUNNEL_TTL] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
|
||||
{
|
||||
struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
|
||||
struct nl_addr *labels;
|
||||
uint8_t ttl = 0;
|
||||
int err;
|
||||
|
||||
|
||||
err = nla_parse_nested(tb, MPLS_IPTUNNEL_MAX, nla, mpls_encap_policy);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!tb[MPLS_IPTUNNEL_DST])
|
||||
return -NLE_INVAL;
|
||||
|
||||
labels = nl_addr_alloc_attr(tb[MPLS_IPTUNNEL_DST], AF_MPLS);
|
||||
if (!labels)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (tb[MPLS_IPTUNNEL_TTL])
|
||||
ttl = nla_get_u8(tb[MPLS_IPTUNNEL_TTL]);
|
||||
|
||||
err = rtnl_route_nh_encap_mpls(nh, labels, ttl);
|
||||
|
||||
nl_addr_put(labels);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mpls_encap_compare(void *_a, void *_b)
|
||||
{
|
||||
struct mpls_iptunnel_encap *a = _a;
|
||||
struct mpls_iptunnel_encap *b = _b;
|
||||
int diff = 0;
|
||||
|
||||
diff |= (a->ttl != b->ttl);
|
||||
diff |= nl_addr_cmp(a->dst, b->dst);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
struct nh_encap_ops mpls_encap_ops = {
|
||||
.encap_type = LWTUNNEL_ENCAP_MPLS,
|
||||
.build_msg = mpls_encap_build_msg,
|
||||
.parse_msg = mpls_encap_parse_msg,
|
||||
.compare = mpls_encap_compare,
|
||||
.dump = mpls_encap_dump,
|
||||
.destructor = mpls_encap_destructor,
|
||||
};
|
||||
|
||||
int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
|
||||
struct nl_addr *addr,
|
||||
uint8_t ttl)
|
||||
{
|
||||
struct mpls_iptunnel_encap *mpls_encap;
|
||||
struct rtnl_nh_encap *rtnh_encap;
|
||||
|
||||
if (!addr)
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (!nl_addr_valid(nl_addr_get_binary_addr(addr),
|
||||
nl_addr_get_len(addr)))
|
||||
return -NLE_INVAL;
|
||||
|
||||
rtnh_encap = calloc(1, sizeof(*rtnh_encap));
|
||||
if (!rtnh_encap)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
mpls_encap = calloc(1, sizeof(*mpls_encap));
|
||||
if (!mpls_encap) {
|
||||
free(rtnh_encap);
|
||||
return -NLE_NOMEM;
|
||||
}
|
||||
|
||||
mpls_encap->dst = nl_addr_get(addr);
|
||||
mpls_encap->ttl = ttl;
|
||||
|
||||
rtnh_encap->priv = mpls_encap;
|
||||
rtnh_encap->ops = &mpls_encap_ops;
|
||||
|
||||
nh_set_encap(nh, rtnh_encap);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1059,4 +1059,5 @@ global:
|
||||
rtnl_route_nh_get_via;
|
||||
rtnl_route_set_ttl_propagate;
|
||||
rtnl_route_get_ttl_propagate;
|
||||
rtnl_route_nh_encap_mpls;
|
||||
} libnl_3_2_29;
|
||||
|
Loading…
Reference in New Issue
Block a user