13b0edf7dSAndrew Thompson /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 43b0edf7dSAndrew Thompson * Copyright (c) 2008 Andrew Thompson. All rights reserved. 53b0edf7dSAndrew Thompson * 63b0edf7dSAndrew Thompson * Redistribution and use in source and binary forms, with or without 73b0edf7dSAndrew Thompson * modification, are permitted provided that the following conditions 83b0edf7dSAndrew Thompson * are met: 93b0edf7dSAndrew Thompson * 1. Redistributions of source code must retain the above copyright 103b0edf7dSAndrew Thompson * notice, this list of conditions and the following disclaimer. 113b0edf7dSAndrew Thompson * 2. Redistributions in binary form must reproduce the above copyright 123b0edf7dSAndrew Thompson * notice, this list of conditions and the following disclaimer in the 133b0edf7dSAndrew Thompson * documentation and/or other materials provided with the distribution. 143b0edf7dSAndrew Thompson * 153b0edf7dSAndrew Thompson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 163b0edf7dSAndrew Thompson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 173b0edf7dSAndrew Thompson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 183b0edf7dSAndrew Thompson * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 193b0edf7dSAndrew Thompson * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 203b0edf7dSAndrew Thompson * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 213b0edf7dSAndrew Thompson * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 223b0edf7dSAndrew Thompson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 233b0edf7dSAndrew Thompson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 243b0edf7dSAndrew Thompson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 253b0edf7dSAndrew Thompson * THE POSSIBILITY OF SUCH DAMAGE. 263b0edf7dSAndrew Thompson */ 273b0edf7dSAndrew Thompson 283b0edf7dSAndrew Thompson #include <sys/param.h> 293b0edf7dSAndrew Thompson #include <sys/ioctl.h> 303b0edf7dSAndrew Thompson #include <sys/socket.h> 313b0edf7dSAndrew Thompson #include <sys/sockio.h> 323b0edf7dSAndrew Thompson #include <net/if.h> 333b0edf7dSAndrew Thompson #include <net/if_gre.h> 343b0edf7dSAndrew Thompson 353b0edf7dSAndrew Thompson #include <ctype.h> 36f325335cSAndrey V. Elsukov #include <limits.h> 373b0edf7dSAndrew Thompson #include <stdio.h> 383b0edf7dSAndrew Thompson #include <stdlib.h> 39f325335cSAndrey V. Elsukov #include <string.h> 403b0edf7dSAndrew Thompson #include <err.h> 413b0edf7dSAndrew Thompson 423b0edf7dSAndrew Thompson #include "ifconfig.h" 433b0edf7dSAndrew Thompson 44*a68e4f7aSGordon Tetlow static const char *GREBITS[] = { 45*a68e4f7aSGordon Tetlow [0] = "ENABLE_CSUM", 46*a68e4f7aSGordon Tetlow [1] = "ENABLE_SEQ", 47*a68e4f7aSGordon Tetlow [2] = "UDPENCAP", 48*a68e4f7aSGordon Tetlow }; 49f325335cSAndrey V. Elsukov 503b0edf7dSAndrew Thompson static void 516e3a9d7fSAlexander V. Chernikov gre_status(if_ctx *ctx) 523b0edf7dSAndrew Thompson { 537fa282e6SAlexander V. Chernikov uint32_t opts = 0, port; 547fa282e6SAlexander V. Chernikov struct ifreq ifr = { .ifr_data = (caddr_t)&opts }; 553b0edf7dSAndrew Thompson 566e3a9d7fSAlexander V. Chernikov if (ioctl_ctx(ctx, GREGKEY, &ifr) == 0) 57f325335cSAndrey V. Elsukov if (opts != 0) 58f325335cSAndrey V. Elsukov printf("\tgrekey: 0x%x (%u)\n", opts, opts); 59f325335cSAndrey V. Elsukov opts = 0; 606e3a9d7fSAlexander V. Chernikov if (ioctl_ctx(ctx, GREGOPTS, &ifr) != 0 || opts == 0) 61f325335cSAndrey V. Elsukov return; 62aee793eeSAndrey V. Elsukov 63aee793eeSAndrey V. Elsukov port = 0; 64aee793eeSAndrey V. Elsukov ifr.ifr_data = (caddr_t)&port; 657fa282e6SAlexander V. Chernikov if (ioctl_ctx_ifr(ctx, GREGPORT, &ifr) == 0 && port != 0) 66aee793eeSAndrey V. Elsukov printf("\tudpport: %u\n", port); 67*a68e4f7aSGordon Tetlow printf("\toptions=%x", opts); 68*a68e4f7aSGordon Tetlow print_bits("options", &opts, 1, GREBITS, nitems(GREBITS)); 69f325335cSAndrey V. Elsukov putchar('\n'); 703b0edf7dSAndrew Thompson } 713b0edf7dSAndrew Thompson 723b0edf7dSAndrew Thompson static void 736e3a9d7fSAlexander V. Chernikov setifgrekey(if_ctx *ctx, const char *val, int dummy __unused) 743b0edf7dSAndrew Thompson { 75f325335cSAndrey V. Elsukov uint32_t grekey = strtol(val, NULL, 0); 767fa282e6SAlexander V. Chernikov struct ifreq ifr = { .ifr_data = (caddr_t)&grekey }; 773b0edf7dSAndrew Thompson 783b0edf7dSAndrew Thompson ifr.ifr_data = (caddr_t)&grekey; 797fa282e6SAlexander V. Chernikov if (ioctl_ctx_ifr(ctx, GRESKEY, &ifr) < 0) 803b0edf7dSAndrew Thompson warn("ioctl (set grekey)"); 813b0edf7dSAndrew Thompson } 823b0edf7dSAndrew Thompson 83f325335cSAndrey V. Elsukov static void 846e3a9d7fSAlexander V. Chernikov setifgreport(if_ctx *ctx, const char *val, int dummy __unused) 85aee793eeSAndrey V. Elsukov { 86aee793eeSAndrey V. Elsukov uint32_t udpport = strtol(val, NULL, 0); 877fa282e6SAlexander V. Chernikov struct ifreq ifr = { .ifr_data = (caddr_t)&udpport }; 88aee793eeSAndrey V. Elsukov 897fa282e6SAlexander V. Chernikov if (ioctl_ctx_ifr(ctx, GRESPORT, &ifr) < 0) 90aee793eeSAndrey V. Elsukov warn("ioctl (set udpport)"); 91aee793eeSAndrey V. Elsukov } 92aee793eeSAndrey V. Elsukov 93aee793eeSAndrey V. Elsukov static void 940c2beef7SAlexander V. Chernikov setifgreopts(if_ctx *ctx, const char *val __unused, int d) 95f325335cSAndrey V. Elsukov { 96f325335cSAndrey V. Elsukov uint32_t opts; 977fa282e6SAlexander V. Chernikov struct ifreq ifr = { .ifr_data = (caddr_t)&opts }; 98f325335cSAndrey V. Elsukov 997fa282e6SAlexander V. Chernikov if (ioctl_ctx_ifr(ctx, GREGOPTS, &ifr) == -1) { 100f325335cSAndrey V. Elsukov warn("ioctl(GREGOPTS)"); 101f325335cSAndrey V. Elsukov return; 102f325335cSAndrey V. Elsukov } 103f325335cSAndrey V. Elsukov 104f325335cSAndrey V. Elsukov if (d < 0) 105f325335cSAndrey V. Elsukov opts &= ~(-d); 106f325335cSAndrey V. Elsukov else 107f325335cSAndrey V. Elsukov opts |= d; 108f325335cSAndrey V. Elsukov 1097fa282e6SAlexander V. Chernikov if (ioctl_ctx(ctx, GRESOPTS, &ifr) == -1) { 110f325335cSAndrey V. Elsukov warn("ioctl(GIFSOPTS)"); 111f325335cSAndrey V. Elsukov return; 112f325335cSAndrey V. Elsukov } 113f325335cSAndrey V. Elsukov } 114f325335cSAndrey V. Elsukov 115f325335cSAndrey V. Elsukov 1163b0edf7dSAndrew Thompson static struct cmd gre_cmds[] = { 1173b0edf7dSAndrew Thompson DEF_CMD_ARG("grekey", setifgrekey), 118aee793eeSAndrey V. Elsukov DEF_CMD_ARG("udpport", setifgreport), 119f325335cSAndrey V. Elsukov DEF_CMD("enable_csum", GRE_ENABLE_CSUM, setifgreopts), 120f325335cSAndrey V. Elsukov DEF_CMD("-enable_csum",-GRE_ENABLE_CSUM,setifgreopts), 121f325335cSAndrey V. Elsukov DEF_CMD("enable_seq", GRE_ENABLE_SEQ, setifgreopts), 122f325335cSAndrey V. Elsukov DEF_CMD("-enable_seq",-GRE_ENABLE_SEQ, setifgreopts), 123aee793eeSAndrey V. Elsukov DEF_CMD("udpencap", GRE_UDPENCAP, setifgreopts), 124aee793eeSAndrey V. Elsukov DEF_CMD("-udpencap",-GRE_UDPENCAP, setifgreopts), 1253b0edf7dSAndrew Thompson }; 1263b0edf7dSAndrew Thompson static struct afswtch af_gre = { 1273b0edf7dSAndrew Thompson .af_name = "af_gre", 1283b0edf7dSAndrew Thompson .af_af = AF_UNSPEC, 1293b0edf7dSAndrew Thompson .af_other_status = gre_status, 1303b0edf7dSAndrew Thompson }; 1313b0edf7dSAndrew Thompson 1323b0edf7dSAndrew Thompson static __constructor void 1333b0edf7dSAndrew Thompson gre_ctor(void) 1343b0edf7dSAndrew Thompson { 135b59dcaeeSXin LI size_t i; 1363b0edf7dSAndrew Thompson 137abd71050SEnji Cooper for (i = 0; i < nitems(gre_cmds); i++) 1383b0edf7dSAndrew Thompson cmd_register(&gre_cmds[i]); 1393b0edf7dSAndrew Thompson af_register(&af_gre); 1403b0edf7dSAndrew Thompson } 141