libnl  3.4.0
nexthop_encap.c
1 
2 #include <netlink-private/netlink.h>
3 #include <netlink-private/types.h>
4 #include <netlink-private/route/nexthop-encap.h>
5 #include <linux/lwtunnel.h>
6 
7 static struct lwtunnel_encap_type {
8  const char *name;
9  struct nh_encap_ops *ops;
10 } lwtunnel_encap_types[__LWTUNNEL_ENCAP_MAX] = {
11  [LWTUNNEL_ENCAP_NONE] = { .name = "none" },
12  [LWTUNNEL_ENCAP_MPLS] = { .name = "mpls", .ops = &mpls_encap_ops },
13  [LWTUNNEL_ENCAP_IP] = { .name = "ip" },
14  [LWTUNNEL_ENCAP_IP6] = { .name = "ip6" },
15  [LWTUNNEL_ENCAP_ILA] = { .name = "ila" },
16  [LWTUNNEL_ENCAP_BPF] = { .name = "bpf" },
17 };
18 
19 static const char *nh_encap_type2str(unsigned int type)
20 {
21  if (type > LWTUNNEL_ENCAP_MAX)
22  return "unknown";
23 
24  return lwtunnel_encap_types[type].name ? : "unknown";
25 }
26 
27 void nh_encap_dump(struct rtnl_nh_encap *rtnh_encap, struct nl_dump_params *dp)
28 {
29  nl_dump(dp, " encap %s ",
30  nh_encap_type2str(rtnh_encap->ops->encap_type));
31 
32  if (rtnh_encap->ops && rtnh_encap->ops->dump)
33  rtnh_encap->ops->dump(rtnh_encap->priv, dp);
34 }
35 
36 int nh_encap_build_msg(struct nl_msg *msg, struct rtnl_nh_encap *rtnh_encap)
37 {
38  struct nlattr *encap;
39  int err;
40 
41  if (!rtnh_encap->ops || !rtnh_encap->ops->build_msg) {
42  NL_DBG(2, "Nexthop encap type not implemented\n");
43  return -NLE_INVAL;
44  }
45 
46  NLA_PUT_U16(msg, RTA_ENCAP_TYPE, rtnh_encap->ops->encap_type);
47 
48  encap = nla_nest_start(msg, RTA_ENCAP);
49  if (!encap)
50  goto nla_put_failure;
51 
52  err = rtnh_encap->ops->build_msg(msg, rtnh_encap->priv);
53  if (err)
54  return err;
55 
56  nla_nest_end(msg, encap);
57 
58  return 0;
59 
60 nla_put_failure:
61  return -NLE_MSGSIZE;
62 }
63 
64 int nh_encap_parse_msg(struct nlattr *encap, struct nlattr *encap_type,
65  struct rtnl_nexthop *rtnh)
66 {
67  uint16_t e_type = nla_get_u16(encap_type);
68 
69  if (e_type == LWTUNNEL_ENCAP_NONE) {
70  NL_DBG(2, "RTA_ENCAP_TYPE should not be LWTUNNEL_ENCAP_NONE\n");
71  return -NLE_INVAL;
72  }
73  if (e_type > LWTUNNEL_ENCAP_MAX) {
74  NL_DBG(2, "Unknown RTA_ENCAP_TYPE: %d\n", e_type);
75  return -NLE_INVAL;
76  }
77 
78  if (!lwtunnel_encap_types[e_type].ops) {
79  NL_DBG(2, "RTA_ENCAP_TYPE %s is not implemented\n",
80  lwtunnel_encap_types[e_type].name);
81  return -NLE_MSGTYPE_NOSUPPORT;
82  }
83 
84  return lwtunnel_encap_types[e_type].ops->parse_msg(encap, rtnh);
85 }
86 
87 int nh_encap_compare(struct rtnl_nh_encap *a, struct rtnl_nh_encap *b)
88 {
89  if (!a && !b)
90  return 0;
91 
92  if ((a && !b) || (!a && b) || (a->ops != b->ops))
93  return 1;
94 
95  if (!a->ops || !a->ops->compare)
96  return 0;
97 
98  return a->ops->compare(a->priv, b->priv);
99 }
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:924
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:656
Dumping parameters.
Definition: types.h:33
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:217
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:961
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:902