5#include <linux/lwtunnel.h>
6#include <linux-private/linux/if_tunnel.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"
36 nl_dump(dp,
"id %llu ", (
unsigned long long)encap_info->id);
39 nl_dump(dp,
"ttl %u ", encap_info->ttl);
42 nl_dump(dp,
"tos %u ", encap_info->tos);
44 if (encap_info->flags) {
45 if (encap_info->flags & TUNNEL_KEY)
47 if (encap_info->flags & TUNNEL_CSUM)
49 if (encap_info->flags & TUNNEL_SEQ)
54static int ip_encap_build_msg(
struct nl_msg *msg,
void *priv)
62 NLA_PUT_U64(msg, LWTUNNEL_IP_ID, htonll(encap_info->id));
64 NLA_PUT_U8(msg, LWTUNNEL_IP_TTL, encap_info->ttl);
66 NLA_PUT_U8(msg, LWTUNNEL_IP_TOS, encap_info->tos);
67 if (encap_info->flags)
68 NLA_PUT_U16(msg, LWTUNNEL_IP_FLAGS, encap_info->flags);
76static void ip_encap_destructor(
void *priv)
84static void *ip_encap_clone(
void *priv)
92 clone = calloc(1,
sizeof(*clone));
100 clone->flags = src->flags;
101 clone->tos = src->tos;
102 clone->ttl = src->ttl;
107static struct nla_policy ip_encap_policy[LWTUNNEL_IP_MAX + 1] = {
108 [LWTUNNEL_IP_DST] = { .type = NLA_BINARY, .minlen = 4, .maxlen = 4 },
109 [LWTUNNEL_IP_SRC] = { .type = NLA_BINARY, .minlen = 4, .maxlen = 4 },
110 [LWTUNNEL_IP_ID] = { .type =
NLA_U64 },
111 [LWTUNNEL_IP_TTL] = { .type =
NLA_U8 },
112 [LWTUNNEL_IP_TOS] = { .type =
NLA_U8 },
113 [LWTUNNEL_IP_FLAGS] = { .type =
NLA_U16 },
116static int ip_encap_parse_msg(
struct nlattr *nla,
119 _nl_auto_rtnl_nh_encap
struct rtnl_nh_encap *nh_encap = NULL;
120 _nl_auto_nl_addr
struct nl_addr *dst = NULL;
121 _nl_auto_nl_addr
struct nl_addr *src = NULL;
122 struct nlattr *tb[LWTUNNEL_IP_MAX + 1];
133 if (!tb[LWTUNNEL_IP_DST])
140 if (tb[LWTUNNEL_IP_SRC]) {
146 if (tb[LWTUNNEL_IP_ID])
148 if (tb[LWTUNNEL_IP_TTL])
150 if (tb[LWTUNNEL_IP_TOS])
152 if (tb[LWTUNNEL_IP_FLAGS])
155 nh_encap = rtnl_nh_encap_alloc();
159 err = rtnl_nh_encap_ip(nh_encap, dst);
164 err = rtnl_nh_set_encap_ip_src(nh_encap, src);
170 err = rtnl_nh_set_encap_ip_id(nh_encap,
id);
176 err = rtnl_nh_set_encap_ip_ttl(nh_encap, ttl);
182 err = rtnl_nh_set_encap_ip_tos(nh_encap, tos);
187 if (tb[LWTUNNEL_IP_FLAGS]) {
188 err = rtnl_nh_set_encap_ip_flags(nh_encap, flags);
193 *encap_out = _nl_steal_pointer(&nh_encap);
198static int ip_encap_compare(
void *_a,
void *_b)
204 diff |= (a->id != b->id);
205 diff |= (a->flags != b->flags);
206 diff |= (a->tos != b->tos);
207 diff |= (a->ttl != b->ttl);
215 .encap_type = LWTUNNEL_ENCAP_IP,
216 .build_msg = ip_encap_build_msg,
217 .parse_msg = ip_encap_parse_msg,
218 .compare = ip_encap_compare,
219 .clone = ip_encap_clone,
220 .dump = ip_encap_dump,
221 .destructor = ip_encap_destructor,
224int rtnl_nh_encap_ip(
struct rtnl_nh_encap *nh_encap,
struct nl_addr *dst)
228 if (!dst || !nh_encap)
233 ip_encap = calloc(1,
sizeof(*ip_encap));
239 nh_encap->priv = ip_encap;
240 nh_encap->ops = &ip_encap_ops;
248 nh_encap, LWTUNNEL_ENCAP_IP);
251struct nl_addr *rtnl_nh_get_encap_ip_dst(
struct rtnl_nh_encap *nh_encap)
255 ip_encap = nh_encap_get_ip(nh_encap);
259 return ip_encap->dst;
266 struct nl_addr *old_src;
268 ip_encap = nh_encap_get_ip(nh_encap);
274 old_src = ip_encap->src;
278 ip_encap->src = NULL;
285struct nl_addr *rtnl_nh_get_encap_ip_src(
struct rtnl_nh_encap *nh_encap)
289 ip_encap = nh_encap_get_ip(nh_encap);
293 return ip_encap->src;
296int rtnl_nh_set_encap_ip_ttl(
struct rtnl_nh_encap *nh_encap, uint8_t ttl)
300 ip_encap = nh_encap_get_ip(nh_encap);
312 ip_encap = nh_encap_get_ip(nh_encap);
316 return ip_encap->ttl;
319int rtnl_nh_set_encap_ip_tos(
struct rtnl_nh_encap *nh_encap, uint8_t tos)
323 ip_encap = nh_encap_get_ip(nh_encap);
335 ip_encap = nh_encap_get_ip(nh_encap);
339 return ip_encap->tos;
342int rtnl_nh_set_encap_ip_id(
struct rtnl_nh_encap *nh_encap, uint64_t
id)
346 ip_encap = nh_encap_get_ip(nh_encap);
354uint64_t rtnl_nh_get_encap_ip_id(
struct rtnl_nh_encap *nh_encap)
358 ip_encap = nh_encap_get_ip(nh_encap);
365int rtnl_nh_set_encap_ip_flags(
struct rtnl_nh_encap *nh_encap, uint16_t flags)
369 ip_encap = nh_encap_get_ip(nh_encap);
373 ip_encap->flags = flags;
377int rtnl_nh_get_encap_ip_flags(
struct rtnl_nh_encap *nh_encap)
381 ip_encap = nh_encap_get_ip(nh_encap);
385 return ip_encap->flags;
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.
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
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.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
#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.
#define NLA_PUT_U64(msg, attrtype, value)
Add 64 bit integer attribute to netlink message.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Attribute validation policy.