netifd: add xfrm tunnel interface support
authorAndré Valentin <avalentin@marcant.net>
Sat, 8 Jun 2019 11:48:09 +0000 (13:48 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Sat, 8 Jun 2019 12:00:22 +0000 (14:00 +0200)
This adds support for xfrm interfaces. These interfaces can be used since
linux 4.19 for IPsec traffic, like VTI interface.
XFRM interfaces are less complicated compared to VTI because they need no IP
tunnel endpoints.

system-linux.c
system.c
system.h

index 2f5bbe1053f59713be1b25a40639f32b97d444b2..c63d8d83bbcf93d865499b297f6df4a75dfcb433 100644 (file)
@@ -2877,6 +2877,63 @@ failure:
 }
 #endif
 
+#ifdef IFLA_XFRM_MAX
+static int system_add_xfrm_tunnel(const char *name, const char *kind,
+                                const unsigned int link, struct blob_attr **tb)
+{
+       struct nl_msg *nlm;
+       struct ifinfomsg ifi = { .ifi_family = AF_UNSPEC, };
+       struct blob_attr *cur;
+       int ret = 0;
+
+       nlm = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL);
+       if (!nlm)
+               return -1;
+
+       nlmsg_append(nlm, &ifi, sizeof(ifi), 0);
+       nla_put_string(nlm, IFLA_IFNAME, name);
+
+       struct nlattr *linkinfo = nla_nest_start(nlm, IFLA_LINKINFO);
+       if (!linkinfo) {
+               ret = -ENOMEM;
+               goto failure;
+       }
+
+       nla_put_string(nlm, IFLA_INFO_KIND, kind);
+       struct nlattr *infodata = nla_nest_start(nlm, IFLA_INFO_DATA);
+       if (!infodata) {
+               ret = -ENOMEM;
+               goto failure;
+       }
+
+       if (link)
+               nla_put_u32(nlm, IFLA_XFRM_LINK, link);
+
+       if ((cur = tb[TUNNEL_ATTR_DATA])) {
+               struct blob_attr *tb_data[__XFRM_DATA_ATTR_MAX];
+               uint32_t if_id = 0;
+
+               blobmsg_parse(xfrm_data_attr_list.params, __XFRM_DATA_ATTR_MAX, tb_data,
+                       blobmsg_data(cur), blobmsg_len(cur));
+
+               if ((cur = tb_data[XFRM_DATA_IF_ID])) {
+                       if ((if_id = blobmsg_get_u32(cur)))
+                               nla_put_u32(nlm, IFLA_XFRM_IF_ID, if_id);
+               }
+
+       }
+
+       nla_nest_end(nlm, infodata);
+       nla_nest_end(nlm, linkinfo);
+
+       return system_rtnl_call(nlm);
+
+failure:
+       nlmsg_free(nlm);
+       return ret;
+}
+#endif
+
 #ifdef IFLA_VXLAN_MAX
 static int system_add_vxlan(const char *name, const unsigned int link, struct blob_attr **tb, bool v6)
 {
@@ -3259,6 +3316,10 @@ int system_add_ip_tunnel(const char *name, struct blob_attr *attr)
        } else if (!strcmp(str, "vtiip6")) {
                return system_add_vti_tunnel(name, "vti6", link, tb, true);
 #endif
+#ifdef IFLA_XFRM_MAX
+       } else if (!strcmp(str, "xfrm")) {
+               return system_add_xfrm_tunnel(name, "xfrm", link, tb);
+#endif
 #ifdef IFLA_VXLAN_MAX
        } else if(!strcmp(str, "vxlan")) {
                return system_add_vxlan(name, link, tb, false);
index dd9ab50d6e7fb93235b1e25b413ab5150d252e89..bbdfef7706653f79c5116e4b8b73342029cfc496 100644 (file)
--- a/system.c
+++ b/system.c
@@ -70,6 +70,15 @@ const struct uci_blob_param_list vti_data_attr_list = {
        .params = vti_data_attrs,
 };
 
+static const struct blobmsg_policy xfrm_data_attrs[__XFRM_DATA_ATTR_MAX] = {
+       [XFRM_DATA_IF_ID] = { .name = "ifid", .type = BLOBMSG_TYPE_INT32 },
+};
+
+const struct uci_blob_param_list xfrm_data_attr_list = {
+       .n_params = __XFRM_DATA_ATTR_MAX,
+       .params = xfrm_data_attrs,
+};
+
 static const struct blobmsg_policy sixrd_data_attrs[__SIXRD_DATA_ATTR_MAX] = {
        [SIXRD_DATA_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING },
        [SIXRD_DATA_RELAY_PREFIX] = { .name = "relay-prefix", .type = BLOBMSG_TYPE_STRING },
index 9fefcaea2d400ed886d93c50007db10fdc30ab35..61c404674cd23832c0bd1f4d535b455c3b494950 100644 (file)
--- a/system.h
+++ b/system.h
@@ -63,6 +63,11 @@ enum vti_data {
        __VTI_DATA_ATTR_MAX
 };
 
+enum xfrm_data {
+       XFRM_DATA_IF_ID,
+       __XFRM_DATA_ATTR_MAX
+};
+
 enum sixrd_data {
        SIXRD_DATA_PREFIX,
        SIXRD_DATA_RELAY_PREFIX,
@@ -86,6 +91,7 @@ enum fmr_data {
 extern const struct uci_blob_param_list vxlan_data_attr_list;
 extern const struct uci_blob_param_list gre_data_attr_list;
 extern const struct uci_blob_param_list vti_data_attr_list;
+extern const struct uci_blob_param_list xfrm_data_attr_list;
 extern const struct uci_blob_param_list sixrd_data_attr_list;
 extern const struct uci_blob_param_list ipip6_data_attr_list;
 extern const struct uci_blob_param_list fmr_data_attr_list;