Adds IPIP tunnel support to netifd.
Following IPIP tunnel parameters can be configured :
   -peeraddr (IPv4 remote address)
   -ipaddr (IPv4 local address)
   -mtu (IPIP tunnel mtu)
   -ttl (time to live of encapsulting packets)
   -tos (type of service either inherit (outer header inherits the value of the 
inner header) or hex value)
   -df (don't fragment flag of encapsulating packets)
   -tunlink (bind tunnel to this interface)

Signed-off-by: Hans Dedecker <dedec...@gmail.com>
---
 system-linux.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/system-linux.c b/system-linux.c
index aca30ca..36657d7 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -204,6 +204,18 @@ system_rtn_aton(const char *src, unsigned int *dst)
        return true;
 }
 
+static bool
+system_tos_aton(const char *src, unsigned *dst)
+{
+       char *e;
+
+       *dst = strtoul(src, &e, 16);
+       if (e == src || *e || *dst > 255)
+               return false;
+
+       return true;
+}
+
 int system_init(void)
 {
        static struct event_socket rtnl_event;
@@ -1709,13 +1721,12 @@ static int system_add_gre_tunnel(const char *name, 
const char *kind,
                char *str = blobmsg_get_string(cur);
                if (strcmp(str, "inherit")) {
                        unsigned uval;
-                       char *e;
 
-                       uval = strtoul(str, &e, 16);
-                       if (e == str || *e || uval > 255) {
+                       if (!system_tos_aton(str, &uval)) {
                                ret = -EINVAL;
                                goto failure;
                        }
+
                        if (v6)
                                flowinfo |= htonl(uval << 20) & 
IP6_FLOWINFO_TCLASS;
                        else
@@ -1842,6 +1853,52 @@ failure:
 }
 #endif
 
+static int system_add_ipip_tunnel(const char *name, const unsigned int link, 
struct blob_attr **tb)
+{
+       struct blob_attr *cur;
+       bool set_df = true;
+       struct ip_tunnel_parm p  = {
+               .link = link,
+               .iph = {
+                       .version = 4,
+                       .ihl = 5,
+                       .protocol = IPPROTO_IPIP,
+               }
+       };
+
+       if ((cur = tb[TUNNEL_ATTR_LOCAL]) &&
+                       inet_pton(AF_INET, blobmsg_data(cur), &p.iph.saddr) < 1)
+               return -EINVAL;
+
+       if ((cur = tb[TUNNEL_ATTR_REMOTE]) &&
+                       inet_pton(AF_INET, blobmsg_data(cur), &p.iph.daddr) < 1)
+               return -EINVAL;
+
+       if ((cur = tb[TUNNEL_ATTR_DF]))
+               set_df = blobmsg_get_bool(cur);
+
+       if ((cur = tb[TUNNEL_ATTR_TTL]))
+               p.iph.ttl = blobmsg_get_u32(cur);
+
+       if ((cur = tb[TUNNEL_ATTR_TOS])) {
+               char *str = blobmsg_get_string(cur);
+               if (strcmp(str, "inherit")) {
+                       unsigned uval;
+
+                       if (!system_tos_aton(str, &uval))
+                               return -EINVAL;
+
+                       p.iph.tos = uval;
+               } else
+                       p.iph.tos = 1;
+       }
+
+       p.iph.frag_off = set_df ? htons(IP_DF) : 0;
+       strncpy(p.name, name, sizeof(p.name));
+
+       return tunnel_ioctl("tunl0", SIOCADDTUNNEL, &p);
+}
+
 static int __system_del_ip_tunnel(const char *name, struct blob_attr **tb)
 {
        struct blob_attr *cur;
@@ -2092,6 +2149,8 @@ failure:
        } else if (!strcmp(str, "gretapip6")) {
                return system_add_gre_tunnel(name, "ip6gretap", link, tb, true);
 #endif
+       } else if (!strcmp(str, "ipip")) {
+               return system_add_ipip_tunnel(name, link, tb);
        }
        else
                return -EINVAL;
-- 
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to