5#include <linux/mpls_iptunnel.h>
6#include <linux/lwtunnel.h>
8#include <netlink/route/nexthop.h>
10#include "nexthop-encap.h"
11#include "nl-aux-core/nl-core.h"
12#include "nl-aux-route/nl-route.h"
28 nl_dump(dp,
"ttl %u ", encap_info->ttl);
31static int mpls_encap_build_msg(
struct nl_msg *msg,
void *priv)
37 NLA_PUT_U8(msg, MPLS_IPTUNNEL_TTL, encap_info->ttl);
45static void mpls_encap_destructor(
void *priv)
52static void *mpls_encap_clone(
void *priv)
60 clone = calloc(1,
sizeof(*clone));
65 clone->ttl = src->ttl;
70static struct nla_policy mpls_encap_policy[MPLS_IPTUNNEL_MAX + 1] = {
71 [MPLS_IPTUNNEL_DST] = { .type =
NLA_U32 },
72 [MPLS_IPTUNNEL_TTL] = { .type =
NLA_U8 },
75static int mpls_encap_parse_msg(
struct nlattr *nla,
79 _nl_auto_nl_addr
struct nl_addr *labels = NULL;
80 struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
88 if (!tb[MPLS_IPTUNNEL_DST])
95 if (tb[MPLS_IPTUNNEL_TTL])
98 nh_encap = rtnl_nh_encap_alloc();
102 err = rtnl_nh_encap_mpls(nh_encap, labels, ttl);
106 *encap_out = _nl_steal_pointer(&nh_encap);
111static int mpls_encap_compare(
void *_a,
void *_b)
117 diff |= (a->ttl != b->ttl);
124 .encap_type = LWTUNNEL_ENCAP_MPLS,
125 .build_msg = mpls_encap_build_msg,
126 .parse_msg = mpls_encap_parse_msg,
127 .compare = mpls_encap_compare,
128 .clone = mpls_encap_clone,
129 .dump = mpls_encap_dump,
130 .destructor = mpls_encap_destructor,
133int rtnl_nh_encap_mpls(
struct rtnl_nh_encap *nh_encap,
struct nl_addr *dst,
138 if (!dst || !nh_encap)
141 mpls_encap = calloc(1,
sizeof(*mpls_encap));
147 mpls_encap->ttl = ttl;
149 nh_encap->priv = mpls_encap;
150 nh_encap->ops = &mpls_encap_ops;
155int rtnl_route_nh_encap_mpls(
struct rtnl_nexthop *nh,
struct nl_addr *addr,
158 _nl_auto_rtnl_nh_encap
struct rtnl_nh_encap *rtnh_encap = NULL;
161 rtnh_encap = rtnl_nh_encap_alloc();
165 ret = rtnl_nh_encap_mpls(rtnh_encap, addr, ttl);
178 nh_encap, LWTUNNEL_ENCAP_MPLS);
181struct nl_addr *rtnl_nh_get_encap_mpls_dst(
struct rtnl_nh_encap *nh_encap)
185 mpls_encap = nh_encap_get_mpls(nh_encap);
189 return mpls_encap->dst;
192struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(
struct rtnl_nexthop *nh)
194 return rtnl_nh_get_encap_mpls_dst(nh->rtnh_encap);
197int rtnl_nh_get_encap_mpls_ttl(
struct rtnl_nh_encap *nh_encap)
201 mpls_encap = nh_encap_get_mpls(nh_encap);
205 return mpls_encap->ttl;
208uint8_t rtnl_route_nh_get_encap_mpls_ttl(
struct rtnl_nexthop *nh)
210 int ttl = rtnl_nh_get_encap_mpls_ttl(nh->rtnh_encap);
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
int rtnl_route_nh_set_encap(struct rtnl_nexthop *nh, struct rtnl_nh_encap *nh_encap)
Set nexthop encapsulation.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Attribute validation policy.