link_gre.c revision dcfb7a77f8709125e97c313cb8ab6ec4d87468f4
1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * link_gre.c gre driver module 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can redistribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: Herbert Xu <herbert@gondor.apana.org.au> 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <net/if.h> 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/types.h> 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/ip.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <linux/if_tunnel.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "rt_names.h" 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "ip_common.h" 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tunnel.h" 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) __attribute__((noreturn)); 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void usage(void) 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ip link { add | set | change | replace | del } NAME\n"); 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " type { gre | gretap } [ remote ADDR ] [ local ADDR ]\n"); 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "\n"); 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Where: NAME := STRING\n"); 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " ADDR := { IP_ADDRESS | any }\n"); 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " TOS := { NUMBER | inherit }\n"); 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " TTL := { 1..255 | inherit }\n"); 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, " KEY := { DOTTED_QUAD | NUMBER }\n"); 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int gre_parse_opt(struct link_util *lu, int argc, char **argv, 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr *n) 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct { 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct nlmsghdr n; 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg i; 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[1024]; 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } req; 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1); 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[IFLA_MAX + 1]; 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *greinfo[IFLA_GRE_MAX + 1]; 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u16 iflags = 0; 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u16 oflags = 0; 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned ikey = 0; 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned okey = 0; 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned saddr = 0; 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned daddr = 0; 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned link = 0; 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u8 pmtudisc = 1; 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u8 ttl = 0; 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u8 tos = 0; 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int len; 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!(n->nlmsg_flags & NLM_F_CREATE)) { 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&req, 0, sizeof(req)); 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)); 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_flags = NLM_F_REQUEST; 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.n.nlmsg_type = RTM_GETLINK; 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.i.ifi_family = preferred_family; 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat req.i.ifi_index = ifi->ifi_index; 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatget_failed: 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Failed to get existing tunnel info.\n"); 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = req.n.nlmsg_len; 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len -= NLMSG_LENGTH(sizeof(*ifi)); 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len < 0) 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto get_failed; 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!tb[IFLA_LINKINFO]) 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto get_failed; 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!linkinfo[IFLA_INFO_DATA]) 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto get_failed; 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(greinfo, IFLA_GRE_MAX, 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat linkinfo[IFLA_INFO_DATA]); 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_IKEY]) 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ikey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_IKEY]); 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_OKEY]) 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat okey = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_OKEY]); 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_IFLAGS]) 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_IFLAGS]); 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_OFLAGS]) 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags = *(__u16 *)RTA_DATA(greinfo[IFLA_GRE_OFLAGS]); 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_LOCAL]) 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat saddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_LOCAL]); 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_REMOTE]) 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat daddr = *(__u32 *)RTA_DATA(greinfo[IFLA_GRE_REMOTE]); 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_PMTUDISC]) 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat pmtudisc = *(__u8 *)RTA_DATA( 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat greinfo[IFLA_GRE_PMTUDISC]); 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_TTL]) 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ttl = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TTL]); 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_TOS]) 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tos = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_TOS]); 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (greinfo[IFLA_GRE_LINK]) 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat link = *(__u8 *)RTA_DATA(greinfo[IFLA_GRE_LINK]); 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!matches(*argv, "key")) { 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_KEY; 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_KEY; 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = get_addr32(*argv); 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0) < 0) { 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Invalid value for \"key\"\n"); 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = htonl(uval); 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ikey = okey = uval; 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "ikey")) { 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_KEY; 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = get_addr32(*argv); 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)<0) { 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "invalid value of \"ikey\"\n"); 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = htonl(uval); 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ikey = uval; 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "okey")) { 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_KEY; 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strchr(*argv, '.')) 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = get_addr32(*argv); 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else { 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)<0) { 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "invalid value of \"okey\"\n"); 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat uval = htonl(uval); 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat okey = uval; 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "seq")) { 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_SEQ; 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_SEQ; 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "iseq")) { 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_SEQ; 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "oseq")) { 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_SEQ; 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "csum")) { 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_CSUM; 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_CSUM; 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "icsum")) { 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_CSUM; 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "ocsum")) { 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_CSUM; 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "nopmtudisc")) { 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat pmtudisc = 0; 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "pmtudisc")) { 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat pmtudisc = 1; 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "remote")) { 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "any")) 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat daddr = get_addr32(*argv); 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "local")) { 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "any")) 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat saddr = get_addr32(*argv); 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "dev")) { 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat link = tnl_ioctl_get_ifindex(*argv); 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (link == 0) 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "ttl") || 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat !matches(*argv, "hoplimit")) { 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned uval; 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "inherit") != 0) { 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_unsigned(&uval, *argv, 0)) 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("invalid TTL\n", *argv); 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (uval > 255) 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("TTL must be <= 255\n", *argv); 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ttl = uval; 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (!matches(*argv, "tos") || 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat !matches(*argv, "tclass") || 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat !matches(*argv, "dsfield")) { 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 uval; 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(*argv, "inherit") != 0) { 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (rtnl_dsfield_a2n(&uval, *argv)) 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat invarg("bad TOS value", *argv); 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tos = uval; 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tos = 1; 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ikey && IN_MULTICAST(ntohl(daddr))) { 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ikey = daddr; 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags |= GRE_KEY; 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!okey && IN_MULTICAST(ntohl(daddr))) { 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat okey = daddr; 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags |= GRE_KEY; 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (IN_MULTICAST(ntohl(daddr)) && !saddr) { 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Broadcast tunnel requires a source address.\n"); 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr32(n, 1024, IFLA_GRE_IKEY, ikey); 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr32(n, 1024, IFLA_GRE_OKEY, okey); 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2); 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2); 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_LOCAL, &saddr, 4); 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4); 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1); 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (link) 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr32(n, 1024, IFLA_GRE_LINK, link); 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1); 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1); 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s1[1024]; 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char s2[64]; 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *local = "any"; 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat const char *remote = "any"; 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned iflags = 0; 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned oflags = 0; 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!tb) 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return; 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_REMOTE]) { 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned addr = *(__u32 *)RTA_DATA(tb[IFLA_GRE_REMOTE]); 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (addr) 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat remote = format_host(AF_INET, 4, &addr, s1, sizeof(s1)); 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "remote %s ", remote); 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_LOCAL]) { 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned addr = *(__u32 *)RTA_DATA(tb[IFLA_GRE_LOCAL]); 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (addr) 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat local = format_host(AF_INET, 4, &addr, s1, sizeof(s1)); 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "local %s ", local); 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_LINK] && *(__u32 *)RTA_DATA(tb[IFLA_GRE_LINK])) { 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat unsigned link = *(__u32 *)RTA_DATA(tb[IFLA_GRE_LINK]); 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char *n = tnl_ioctl_get_ifname(link); 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (n) 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "dev %s ", n); 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "dev %u ", link); 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_TTL] && *(__u8 *)RTA_DATA(tb[IFLA_GRE_TTL])) 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ttl %d ", *(__u8 *)RTA_DATA(tb[IFLA_GRE_TTL])); 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ttl inherit "); 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_TOS] && *(__u8 *)RTA_DATA(tb[IFLA_GRE_TOS])) { 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int tos = *(__u8 *)RTA_DATA(tb[IFLA_GRE_TOS]); 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("tos ", f); 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tos == 1) 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("inherit ", f); 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat else 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "0x%x ", tos); 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_PMTUDISC] && 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat !*(__u8 *)RTA_DATA(tb[IFLA_GRE_PMTUDISC])) 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("nopmtudisc ", f); 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_IFLAGS]) 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iflags = *(__u16 *)RTA_DATA(tb[IFLA_GRE_IFLAGS]); 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[IFLA_GRE_OFLAGS]) 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat oflags = *(__u16 *)RTA_DATA(tb[IFLA_GRE_OFLAGS]); 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iflags & GRE_KEY && tb[IFLA_GRE_IKEY] && 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *(__u32 *)RTA_DATA(tb[IFLA_GRE_IKEY])) { 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_IKEY]), s2, sizeof(s2)); 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ikey %s ", s2); 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (oflags & GRE_KEY && tb[IFLA_GRE_OKEY] && 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *(__u32 *)RTA_DATA(tb[IFLA_GRE_OKEY])) { 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_OKEY]), s2, sizeof(s2)); 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "ikey %s ", s2); 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iflags & GRE_SEQ) 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("iseq ", f); 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (oflags & GRE_SEQ) 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("oseq ", f); 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (iflags & GRE_CSUM) 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("icsum ", f); 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (oflags & GRE_CSUM) 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fputs("ocsum ", f); 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct link_util gre_link_util = { 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "gre", 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .maxattr = IFLA_GRE_MAX, 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_opt = gre_parse_opt, 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_opt = gre_print_opt, 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct link_util gretap_link_util = { 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "gretap", 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .maxattr = IFLA_GRE_MAX, 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_opt = gre_parse_opt, 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_opt = gre_print_opt, 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 369