1237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu/* 2237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * link_gre.c gre driver module 3237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * 4237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * This program is free software; you can redistribute it and/or 5237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * modify it under the terms of the GNU General Public License 6237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * as published by the Free Software Foundation; either version 7237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * 2 of the License, or (at your option) any later version. 8237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * 9237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * Authors: Herbert Xu <herbert@gondor.apana.org.au> 10237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu * 11237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu */ 12237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 13237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include <string.h> 14237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include <net/if.h> 15237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include <sys/types.h> 16237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include <sys/socket.h> 17237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include <arpa/inet.h> 18237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 191957a322c9932e1a1d2ca1fd37ce4b335ceb7113Stephen Hemminger#include <linux/ip.h> 201957a322c9932e1a1d2ca1fd37ce4b335ceb7113Stephen Hemminger#include <linux/if_tunnel.h> 21237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include "rt_names.h" 22237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include "utils.h" 23237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include "ip_common.h" 24237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu#include "tunnel.h" 25237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 26561e650eff679296d3f4c12657721ae769cbc187vadimkstatic void print_usage(FILE *f) 27561e650eff679296d3f4c12657721ae769cbc187vadimk{ 28561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, "Usage: ip link { add | set | change | replace | del } NAME\n"); 29561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " type { gre | gretap } [ remote ADDR ] [ local ADDR ]\n"); 30561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); 31561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); 3280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fprintf(f, " [ noencap ] [ encap { fou | gue | none } ]\n"); 3380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fprintf(f, " [ encap-sport PORT ] [ encap-dport PORT ]\n"); 34858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert fprintf(f, " [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n"); 35561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, "\n"); 36561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, "Where: NAME := STRING\n"); 37561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " ADDR := { IP_ADDRESS | any }\n"); 38561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " TOS := { NUMBER | inherit }\n"); 39561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " TTL := { 1..255 | inherit }\n"); 40561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, " KEY := { DOTTED_QUAD | NUMBER }\n"); 41561e650eff679296d3f4c12657721ae769cbc187vadimk} 42561e650eff679296d3f4c12657721ae769cbc187vadimk 43237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustatic void usage(void) __attribute__((noreturn)); 44237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustatic void usage(void) 45237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu{ 46561e650eff679296d3f4c12657721ae769cbc187vadimk print_usage(stderr); 47237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu exit(-1); 48237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu} 49237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 50237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustatic int gre_parse_opt(struct link_util *lu, int argc, char **argv, 51237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu struct nlmsghdr *n) 52237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu{ 5372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct { 5472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct nlmsghdr n; 5572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct ifinfomsg i; 56bde5baa5476cd8d7d33afc42170dc984f3717e14Jetchko Jekov char buf[16384]; 5772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu } req; 5872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct ifinfomsg *ifi = (struct ifinfomsg *)(n + 1); 5972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct rtattr *tb[IFLA_MAX + 1]; 6072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 6172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu struct rtattr *greinfo[IFLA_GRE_MAX + 1]; 62237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu __u16 iflags = 0; 63237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu __u16 oflags = 0; 64237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned ikey = 0; 65237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned okey = 0; 66237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned saddr = 0; 67237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned daddr = 0; 6872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu unsigned link = 0; 6972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu __u8 pmtudisc = 1; 7072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu __u8 ttl = 0; 7172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu __u8 tos = 0; 7272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu int len; 7380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 encaptype = 0; 7480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 encapflags = 0; 7580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 encapsport = 0; 7680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 encapdport = 0; 77926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni __u8 metadata = 0; 7872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 7972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (!(n->nlmsg_flags & NLM_F_CREATE)) { 8072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu memset(&req, 0, sizeof(req)); 8172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 8272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu req.n.nlmsg_len = NLMSG_LENGTH(sizeof(*ifi)); 8372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu req.n.nlmsg_flags = NLM_F_REQUEST; 8472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu req.n.nlmsg_type = RTM_GETLINK; 8572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu req.i.ifi_family = preferred_family; 8672c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu req.i.ifi_index = ifi->ifi_index; 8772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 88c079e121a73af5eb49e003b13607e8a690331df6Stephen Hemminger if (rtnl_talk(&rth, &req.n, &req.n, sizeof(req)) < 0) { 8972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xuget_failed: 9072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu fprintf(stderr, 9172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu "Failed to get existing tunnel info.\n"); 9272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu return -1; 9372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu } 9472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 9572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu len = req.n.nlmsg_len; 9672c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu len -= NLMSG_LENGTH(sizeof(*ifi)); 9772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (len < 0) 9872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu goto get_failed; 9972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 10072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu parse_rtattr(tb, IFLA_MAX, IFLA_RTA(&req.i), len); 10172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 10272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (!tb[IFLA_LINKINFO]) 10372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu goto get_failed; 10472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 10572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); 10672c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 10772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (!linkinfo[IFLA_INFO_DATA]) 10872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu goto get_failed; 10972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 11072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu parse_rtattr_nested(greinfo, IFLA_GRE_MAX, 11172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu linkinfo[IFLA_INFO_DATA]); 11272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 11372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_IKEY]) 114ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger ikey = rta_getattr_u32(greinfo[IFLA_GRE_IKEY]); 11572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 11672c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_OKEY]) 117ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger okey = rta_getattr_u32(greinfo[IFLA_GRE_OKEY]); 11872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 11972c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_IFLAGS]) 120ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger iflags = rta_getattr_u16(greinfo[IFLA_GRE_IFLAGS]); 12172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 12272c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_OFLAGS]) 123ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger oflags = rta_getattr_u16(greinfo[IFLA_GRE_OFLAGS]); 12472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 12572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_LOCAL]) 126ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger saddr = rta_getattr_u32(greinfo[IFLA_GRE_LOCAL]); 12772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 12872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_REMOTE]) 129ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger daddr = rta_getattr_u32(greinfo[IFLA_GRE_REMOTE]); 13072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 13172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_PMTUDISC]) 132ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger pmtudisc = rta_getattr_u8( 13372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu greinfo[IFLA_GRE_PMTUDISC]); 13472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 13572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_TTL]) 136ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger ttl = rta_getattr_u8(greinfo[IFLA_GRE_TTL]); 13772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 13872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_TOS]) 139ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger tos = rta_getattr_u8(greinfo[IFLA_GRE_TOS]); 14072c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu 14172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (greinfo[IFLA_GRE_LINK]) 142ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger link = rta_getattr_u8(greinfo[IFLA_GRE_LINK]); 14380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 14480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (greinfo[IFLA_GRE_ENCAP_TYPE]) 14580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]); 14680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (greinfo[IFLA_GRE_ENCAP_FLAGS]) 14780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapflags = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_FLAGS]); 14880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (greinfo[IFLA_GRE_ENCAP_SPORT]) 14980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]); 15080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (greinfo[IFLA_GRE_ENCAP_DPORT]) 15180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]); 152926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni 153926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni if (greinfo[IFLA_GRE_COLLECT_METADATA]) 154926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni metadata = 1; 15572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu } 156237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 157237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu while (argc > 0) { 158237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (!matches(*argv, "key")) { 159237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned uval; 160237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 161237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 162237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_KEY; 163237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_KEY; 164237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strchr(*argv, '.')) 165237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = get_addr32(*argv); 166237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else { 167237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (get_unsigned(&uval, *argv, 0) < 0) { 168237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(stderr, 16914645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk "Invalid value for \"key\": \"%s\"; it should be an unsigned integer\n", *argv); 170237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu exit(-1); 171237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 172237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = htonl(uval); 173237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 174237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 175237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu ikey = okey = uval; 176237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "ikey")) { 177237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned uval; 178237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 179237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 180237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_KEY; 181237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strchr(*argv, '.')) 182237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = get_addr32(*argv); 183237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else { 184237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (get_unsigned(&uval, *argv, 0)<0) { 18514645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "invalid value for \"ikey\": \"%s\"; it should be an unsigned integer\n", *argv); 186237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu exit(-1); 187237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 188237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = htonl(uval); 189237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 190237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu ikey = uval; 191237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "okey")) { 192237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned uval; 193237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 194237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 195237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_KEY; 196237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strchr(*argv, '.')) 197237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = get_addr32(*argv); 198237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else { 199237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (get_unsigned(&uval, *argv, 0)<0) { 20014645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "invalid value for \"okey\": \"%s\"; it should be an unsigned integer\n", *argv); 201237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu exit(-1); 202237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 203237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu uval = htonl(uval); 204237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 205237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu okey = uval; 206237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "seq")) { 207237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_SEQ; 208237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_SEQ; 209237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "iseq")) { 210237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_SEQ; 211237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "oseq")) { 212237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_SEQ; 213237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "csum")) { 214237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_CSUM; 215237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_CSUM; 216237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "icsum")) { 217237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_CSUM; 218237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "ocsum")) { 219237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_CSUM; 220237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "nopmtudisc")) { 22172c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu pmtudisc = 0; 222237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "pmtudisc")) { 22372c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu pmtudisc = 1; 224237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "remote")) { 225237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 226237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strcmp(*argv, "any")) 227237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu daddr = get_addr32(*argv); 228237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "local")) { 229237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 230237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strcmp(*argv, "any")) 231237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu saddr = get_addr32(*argv); 232237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "dev")) { 233237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 234ea71beacacb9ebf756bbc250c71df59ec2f46243Stephen Hemminger link = if_nametoindex(*argv); 2350cb6bb51b4eb9bd08e152342b95dcae13287dafdCong Wang if (link == 0) { 2360cb6bb51b4eb9bd08e152342b95dcae13287dafdCong Wang fprintf(stderr, "Cannot find device \"%s\"\n", 2370cb6bb51b4eb9bd08e152342b95dcae13287dafdCong Wang *argv); 238237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu exit(-1); 2390cb6bb51b4eb9bd08e152342b95dcae13287dafdCong Wang } 240237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "ttl") || 241237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu !matches(*argv, "hoplimit")) { 242237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned uval; 243237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 244237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 245237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strcmp(*argv, "inherit") != 0) { 246237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (get_unsigned(&uval, *argv, 0)) 247237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu invarg("invalid TTL\n", *argv); 248237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (uval > 255) 249237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu invarg("TTL must be <= 255\n", *argv); 250237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu ttl = uval; 251237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 252237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else if (!matches(*argv, "tos") || 253237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu !matches(*argv, "tclass") || 254237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu !matches(*argv, "dsfield")) { 255237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu __u32 uval; 256237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 257237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu NEXT_ARG(); 258237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (strcmp(*argv, "inherit") != 0) { 259237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (rtnl_dsfield_a2n(&uval, *argv)) 260237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu invarg("bad TOS value", *argv); 261237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu tos = uval; 262237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } else 263237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu tos = 1; 26480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "noencap") == 0) { 26580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encaptype = TUNNEL_ENCAP_NONE; 26680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "encap") == 0) { 26780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert NEXT_ARG(); 26880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (strcmp(*argv, "fou") == 0) 26980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encaptype = TUNNEL_ENCAP_FOU; 27080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else if (strcmp(*argv, "gue") == 0) 27180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encaptype = TUNNEL_ENCAP_GUE; 27280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else if (strcmp(*argv, "none") == 0) 27380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encaptype = TUNNEL_ENCAP_NONE; 27480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else 27580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert invarg("Invalid encap type.", *argv); 27680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "encap-sport") == 0) { 27780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert NEXT_ARG(); 27880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (strcmp(*argv, "auto") == 0) 27980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapsport = 0; 28080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else if (get_u16(&encapsport, *argv, 0)) 28180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert invarg("Invalid source port.", *argv); 28280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "encap-dport") == 0) { 28380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert NEXT_ARG(); 28480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (get_u16(&encapdport, *argv, 0)) 28580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert invarg("Invalid destination port.", *argv); 28680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "encap-csum") == 0) { 28780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapflags |= TUNNEL_ENCAP_FLAG_CSUM; 28880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "noencap-csum") == 0) { 28980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM; 29080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "encap-udp6-csum") == 0) { 29180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapflags |= TUNNEL_ENCAP_FLAG_CSUM6; 29280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } else if (strcmp(*argv, "noencap-udp6-csum") == 0) { 29380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6; 294858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert } else if (strcmp(*argv, "encap-remcsum") == 0) { 295858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; 296858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert } else if (strcmp(*argv, "noencap-remcsum") == 0) { 297858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; 298926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni } else if (strcmp(*argv, "external") == 0) { 299926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni metadata = 1; 3000612519e011812276ade512d4a7f8113497f64edStephen Hemminger } else 301237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu usage(); 302237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu argc--; argv++; 303237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 304237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 305237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (!ikey && IN_MULTICAST(ntohl(daddr))) { 306237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu ikey = daddr; 307237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu iflags |= GRE_KEY; 308237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 309237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (!okey && IN_MULTICAST(ntohl(daddr))) { 310237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu okey = daddr; 311237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu oflags |= GRE_KEY; 312237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 313237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (IN_MULTICAST(ntohl(daddr)) && !saddr) { 31414645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "A broadcast tunnel requires a source address.\n"); 315237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu return -1; 316237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 317237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 318237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr32(n, 1024, IFLA_GRE_IKEY, ikey); 319237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr32(n, 1024, IFLA_GRE_OKEY, okey); 320237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2); 321237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2); 322237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr_l(n, 1024, IFLA_GRE_LOCAL, &saddr, 4); 323237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4); 32472c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1); 32572c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu if (link) 32672c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu addattr32(n, 1024, IFLA_GRE_LINK, link); 32772c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1); 32872c771b20e38eaabb7699625fcdc144a51771f9cHerbert Xu addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1); 329237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 33080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype); 33180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags); 33280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport)); 33380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport)); 334926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni if (metadata) 335926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0); 33680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 337237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu return 0; 338237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu} 339237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 340237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustatic void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 341237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu{ 342237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu char s1[1024]; 343237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu char s2[64]; 344237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu const char *local = "any"; 345237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu const char *remote = "any"; 346237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned iflags = 0; 347237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu unsigned oflags = 0; 348237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 349237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (!tb) 350237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu return; 351237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 352237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tb[IFLA_GRE_REMOTE]) { 353ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger unsigned addr = rta_getattr_u32(tb[IFLA_GRE_REMOTE]); 354237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 355237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (addr) 356237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu remote = format_host(AF_INET, 4, &addr, s1, sizeof(s1)); 357237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 358237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 359237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "remote %s ", remote); 360237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 361237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tb[IFLA_GRE_LOCAL]) { 362ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger unsigned addr = rta_getattr_u32(tb[IFLA_GRE_LOCAL]); 363237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 364237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (addr) 365237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu local = format_host(AF_INET, 4, &addr, s1, sizeof(s1)); 366237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 367237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 368237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "local %s ", local); 369237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 370ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger if (tb[IFLA_GRE_LINK] && rta_getattr_u32(tb[IFLA_GRE_LINK])) { 371ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger unsigned link = rta_getattr_u32(tb[IFLA_GRE_LINK]); 372ea71beacacb9ebf756bbc250c71df59ec2f46243Stephen Hemminger const char *n = if_indextoname(link, s2); 373237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 374237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (n) 375237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "dev %s ", n); 376237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else 377237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "dev %u ", link); 378237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 379237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 380ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger if (tb[IFLA_GRE_TTL] && rta_getattr_u8(tb[IFLA_GRE_TTL])) 381ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger fprintf(f, "ttl %d ", rta_getattr_u8(tb[IFLA_GRE_TTL])); 382237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else 383237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "ttl inherit "); 384237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 385ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger if (tb[IFLA_GRE_TOS] && rta_getattr_u8(tb[IFLA_GRE_TOS])) { 386ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger int tos = rta_getattr_u8(tb[IFLA_GRE_TOS]); 387237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 388237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("tos ", f); 389237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tos == 1) 390237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("inherit ", f); 391237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu else 392237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "0x%x ", tos); 393237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 394237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 395237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tb[IFLA_GRE_PMTUDISC] && 396ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger !rta_getattr_u8(tb[IFLA_GRE_PMTUDISC])) 397237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("nopmtudisc ", f); 398237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 399237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tb[IFLA_GRE_IFLAGS]) 400ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger iflags = rta_getattr_u16(tb[IFLA_GRE_IFLAGS]); 401237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 402237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (tb[IFLA_GRE_OFLAGS]) 403ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger oflags = rta_getattr_u16(tb[IFLA_GRE_OFLAGS]); 404237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 405718165534d0c57ea23c536f57affe7f04a33199aStephen Hemminger if ((iflags & GRE_KEY) && tb[IFLA_GRE_IKEY]) { 406237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_IKEY]), s2, sizeof(s2)); 407237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fprintf(f, "ikey %s ", s2); 408237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 409237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 410718165534d0c57ea23c536f57affe7f04a33199aStephen Hemminger if ((oflags & GRE_KEY) && tb[IFLA_GRE_OKEY]) { 411237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu inet_ntop(AF_INET, RTA_DATA(tb[IFLA_GRE_OKEY]), s2, sizeof(s2)); 412718165534d0c57ea23c536f57affe7f04a33199aStephen Hemminger fprintf(f, "okey %s ", s2); 413237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu } 414237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 415237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (iflags & GRE_SEQ) 416237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("iseq ", f); 417237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (oflags & GRE_SEQ) 418237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("oseq ", f); 419237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (iflags & GRE_CSUM) 420237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("icsum ", f); 421237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu if (oflags & GRE_CSUM) 422237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu fputs("ocsum ", f); 42380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 424926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni if (tb[IFLA_GRE_COLLECT_METADATA]) 425926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni fputs("external ", f); 426926b39e1feffdacff52fe8b7eafe0ba3b8c9ff59Paolo Abeni 42780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (tb[IFLA_GRE_ENCAP_TYPE] && 42880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert *(__u16 *)RTA_DATA(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { 42980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]); 43080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 flags = rta_getattr_u16(tb[IFLA_GRE_ENCAP_FLAGS]); 43180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 sport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_SPORT]); 43280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert __u16 dport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_DPORT]); 43380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 43480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("encap ", f); 43580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert switch (type) { 43680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert case TUNNEL_ENCAP_FOU: 43780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("fou ", f); 43880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert break; 43980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert case TUNNEL_ENCAP_GUE: 44080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("gue ", f); 44180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert break; 44280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert default: 44380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("unknown ", f); 44480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert break; 44580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } 44680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 44780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (sport == 0) 44880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("encap-sport auto ", f); 44980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else 45080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fprintf(f, "encap-sport %u", ntohs(sport)); 45180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 45280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fprintf(f, "encap-dport %u ", ntohs(dport)); 45380c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 45480c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (flags & TUNNEL_ENCAP_FLAG_CSUM) 45580c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("encap-csum ", f); 45680c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else 45780c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("noencap-csum ", f); 45880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert 45980c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert if (flags & TUNNEL_ENCAP_FLAG_CSUM6) 46080c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("encap-csum6 ", f); 46180c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert else 46280c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert fputs("noencap-csum6 ", f); 463858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert 464858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert if (flags & TUNNEL_ENCAP_FLAG_REMCSUM) 465858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert fputs("encap-remcsum ", f); 466858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert else 467858dbb208e3934525674252a6b6cf7d36a9de191Tom Herbert fputs("noencap-remcsum ", f); 46880c24b097e2f943676b20c0b72a5c95da2d0285fTom Herbert } 469237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu} 470237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 471561e650eff679296d3f4c12657721ae769cbc187vadimkstatic void gre_print_help(struct link_util *lu, int argc, char **argv, 472561e650eff679296d3f4c12657721ae769cbc187vadimk FILE *f) 473561e650eff679296d3f4c12657721ae769cbc187vadimk{ 474561e650eff679296d3f4c12657721ae769cbc187vadimk print_usage(f); 475561e650eff679296d3f4c12657721ae769cbc187vadimk} 476561e650eff679296d3f4c12657721ae769cbc187vadimk 477237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustruct link_util gre_link_util = { 478237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .id = "gre", 479237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .maxattr = IFLA_GRE_MAX, 480237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .parse_opt = gre_parse_opt, 481237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .print_opt = gre_print_opt, 482561e650eff679296d3f4c12657721ae769cbc187vadimk .print_help = gre_print_help, 483237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu}; 484237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu 485237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xustruct link_util gretap_link_util = { 486237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .id = "gretap", 487237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .maxattr = IFLA_GRE_MAX, 488237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .parse_opt = gre_parse_opt, 489237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu .print_opt = gre_print_opt, 490561e650eff679296d3f4c12657721ae769cbc187vadimk .print_help = gre_print_help, 491237d9e82c56918a1c972e6f30dd3cf1cfb957412Herbert Xu}; 492