libnl  3.4.0
nh_encap_mpls.c
1 
2 #include <netlink-private/netlink.h>
3 #include <netlink-private/types.h>
4 #include <netlink-private/route/nexthop-encap.h>
5 #include <netlink/route/nexthop.h>
6 #include <linux/mpls_iptunnel.h>
7 #include <linux/lwtunnel.h>
8 
10  struct nl_addr *dst;
11  uint8_t ttl;
12 };
13 
14 static void mpls_encap_dump(void *priv, struct nl_dump_params *dp)
15 {
16  struct mpls_iptunnel_encap *encap_info = priv;
17  char buf[256];
18 
19  nl_dump(dp, "%s ", nl_addr2str(encap_info->dst, buf, sizeof(buf)));
20 
21  if (encap_info->ttl)
22  nl_dump(dp, "ttl %u ", encap_info->ttl);
23 }
24 
25 static int mpls_encap_build_msg(struct nl_msg *msg, void *priv)
26 {
27  struct mpls_iptunnel_encap *encap_info = priv;
28 
29  NLA_PUT_ADDR(msg, MPLS_IPTUNNEL_DST, encap_info->dst);
30  if (encap_info->ttl)
31  NLA_PUT_U8(msg, MPLS_IPTUNNEL_TTL, encap_info->ttl);
32 
33  return 0;
34 
35 nla_put_failure:
36  return -NLE_MSGSIZE;
37 }
38 
39 static void mpls_encap_destructor(void *priv)
40 {
41  struct mpls_iptunnel_encap *encap_info = priv;
42 
43  nl_addr_put(encap_info->dst);
44 }
45 
46 static struct nla_policy mpls_encap_policy[MPLS_IPTUNNEL_MAX + 1] = {
47  [MPLS_IPTUNNEL_DST] = { .type = NLA_U32 },
48  [MPLS_IPTUNNEL_TTL] = { .type = NLA_U8 },
49 };
50 
51 static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
52 {
53  struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
54  struct nl_addr *labels;
55  uint8_t ttl = 0;
56  int err;
57 
58 
59  err = nla_parse_nested(tb, MPLS_IPTUNNEL_MAX, nla, mpls_encap_policy);
60  if (err)
61  return err;
62 
63  if (!tb[MPLS_IPTUNNEL_DST])
64  return -NLE_INVAL;
65 
66  labels = nl_addr_alloc_attr(tb[MPLS_IPTUNNEL_DST], AF_MPLS);
67  if (!labels)
68  return -NLE_NOMEM;
69 
70  if (tb[MPLS_IPTUNNEL_TTL])
71  ttl = nla_get_u8(tb[MPLS_IPTUNNEL_TTL]);
72 
73  err = rtnl_route_nh_encap_mpls(nh, labels, ttl);
74 
75  nl_addr_put(labels);
76 
77  return err;
78 }
79 
80 static int mpls_encap_compare(void *_a, void *_b)
81 {
82  struct mpls_iptunnel_encap *a = _a;
83  struct mpls_iptunnel_encap *b = _b;
84  int diff = 0;
85 
86  diff |= (a->ttl != b->ttl);
87  diff |= nl_addr_cmp(a->dst, b->dst);
88 
89  return diff;
90 }
91 
92 struct nh_encap_ops mpls_encap_ops = {
93  .encap_type = LWTUNNEL_ENCAP_MPLS,
94  .build_msg = mpls_encap_build_msg,
95  .parse_msg = mpls_encap_parse_msg,
96  .compare = mpls_encap_compare,
97  .dump = mpls_encap_dump,
98  .destructor = mpls_encap_destructor,
99 };
100 
101 int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
102  struct nl_addr *addr,
103  uint8_t ttl)
104 {
105  struct mpls_iptunnel_encap *mpls_encap;
106  struct rtnl_nh_encap *rtnh_encap;
107 
108  if (!addr)
109  return -NLE_INVAL;
110 
112  nl_addr_get_len(addr)))
113  return -NLE_INVAL;
114 
115  rtnh_encap = calloc(1, sizeof(*rtnh_encap));
116  if (!rtnh_encap)
117  return -NLE_NOMEM;
118 
119  mpls_encap = calloc(1, sizeof(*mpls_encap));
120  if (!mpls_encap) {
121  free(rtnh_encap);
122  return -NLE_NOMEM;
123  }
124 
125  mpls_encap->dst = nl_addr_get(addr);
126  mpls_encap->ttl = ttl;
127 
128  rtnh_encap->priv = mpls_encap;
129  rtnh_encap->ops = &mpls_encap_ops;
130 
131  nh_set_encap(nh, rtnh_encap);
132 
133  return 0;
134 }
8 bit integer
Definition: attr.h:41
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition: addr.c:585
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
Definition: attr.h:288
Attribute validation policy.
Definition: attr.h:69
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:606
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:523
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
Definition: addr.c:262
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:199
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:999
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:539
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
int nl_addr_valid(const char *addr, int family)
Check if address string is parseable for a specific address family.
Definition: addr.c:661
32 bit integer
Definition: attr.h:43
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:961
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:945
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:933
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:991