From f5aa586d20c56705d7fc7f0101f73d58bfd7b5c7 Mon Sep 17 00:00:00 2001 From: "Walter F.J. Mueller" Date: Sun, 7 May 2017 18:23:35 +0200 Subject: [PATCH] tools for setting up ethernet bridge and tap - add ip_create_br: create bride and convert default ethernet interface - add ip_create_tap: create use-mode tap device - add ip_inspect: helper script --- doc/CHANGELOG.md | 6 +- tools/bin/ip_create_br | 73 +++++++++++++++ tools/bin/ip_create_tap | 51 +++++++++++ tools/bin/ip_inspect | 161 +++++++++++++++++++++++++++++++++ tools/man/man1/ip_create_br.1 | 42 +++++++++ tools/man/man1/ip_create_tap.1 | 40 ++++++++ 6 files changed, 372 insertions(+), 1 deletion(-) create mode 100755 tools/bin/ip_create_br create mode 100755 tools/bin/ip_create_tap create mode 100755 tools/bin/ip_inspect create mode 100644 tools/man/man1/ip_create_br.1 create mode 100644 tools/man/man1/ip_create_tap.1 diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 399123de..ca7c76d5 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -25,13 +25,17 @@ The full set of tests is only run for tagged releases. - RSX11-M uses buffer chaining, will not work ### Summary +- tools for setting up ethernet bridge and tap + - add ip_create_br: create bride and convert default ethernet interface + - add ip_create_tap: create use-mode tap device + - add ip_inspect: helper script - re-arrange rawio commands for rlc and rlp - RtclRlink(Connect|Port): drop M_rawio; add M_rawread,M_rawrblk,M_rawwblk - RtclRlinkPort: LogFileName(): returns now const std::string& - BUGFIXes for backend - RlinkPort: BUGFIX: RawRead(): proper irc for exactsize=false - Rexception: BUGFIX: add fErrtxt for proper what() return -- sys_w11a_n(2|3): use SWI(7:6) to allow fx2 debug via LEDs +- sys_w11a_n(2|3): use SWI(7:6) to allow fx2 debug via LEDs - BUGFIX: resolve hangup of fx2 USB controller - was caused by inconsistent use of rx fifo thresholds - adding more lines to monitor output (fsm_* lines for state tracking) diff --git a/tools/bin/ip_create_br b/tools/bin/ip_create_br new file mode 100755 index 00000000..b347fe21 --- /dev/null +++ b/tools/bin/ip_create_br @@ -0,0 +1,73 @@ +#!/bin/bash +# $Id: ip_create_br 873 2017-04-14 11:56:29Z mueller $ +# +# Copyright 2017- by Walter F.J. Mueller +# License disclaimer see License.txt in $RETROBASE directory +# +# Revision History: +# Date Rev Version Comment +# 2017-04-14 873 1.0 Initial version +# 2017-03-04 858 0.5 First draft +# + +# some preparations +defeif=$(ip_inspect defeif) + +if [[ -z $defeif ]]; then + echo "ip_create_br-I: default interface not found" + exit 1 +fi + +hostaddr=$(ip_inspect addr4 $defeif addr) +hostmask=$(ip_inspect addr4 $defeif mask) +hostbcast=$(ip_inspect addr4 $defeif bcast) +hostdgway=`route -n | grep ^0.0.0.0 |\ + gawk -- '{ print $2 }'` + +if [[ -z "$hostaddr" || -z "$hostmask" || -z "$hostbcast" || -z "$hostdgway" ]] +then + echo "ip_create_br-E: failed to determine current setup" + exit 1 +fi + +# echo $defeif +# echo $hostaddr +# echo $hostmask +# echo $hostbcast +# echo $hostdgway + +# sanitize PATH, use what sudo has +export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +which_ip=$(which ip) +which_ifconfig=$(which ifconfig) +which_brctl=$(which brctl) +which_route=$(which route) + +if [[ -z "$which_ip" || -z "$which_ifconfig" || + -z "$which_brctl" || -z "$which_route" ]] +then + echo "ip_create_br-E: ip, ifconfig, brctl, or route not in PATH" + exit 1 +fi + +if $which_ifconfig | grep -q "br0\s*Link" +then + echo "ip_create_br-I: Bridge br0 already exists" + exit 1 +fi + +# print info so that sudo password prompt is expected +if [[ $(id -u) -ne 0 ]] ; then echo "ip_create_br-I: requires sudo" ; fi + +sudo $which_brctl addbr br0 +sudo $which_brctl addif br0 $defeif +sudo $which_brctl setfd br0 0 +sudo $which_ifconfig $defeif 0.0.0.0 +sudo $which_ifconfig br0 $hostaddr netmask $hostmask broadcast $hostbcast up +# set the default route to the br0 interface +sudo $which_route add -net 0.0.0.0/0 gw $hostdgway + +# +$which_ifconfig br0 +$which_route diff --git a/tools/bin/ip_create_tap b/tools/bin/ip_create_tap new file mode 100755 index 00000000..8409c343 --- /dev/null +++ b/tools/bin/ip_create_tap @@ -0,0 +1,51 @@ +#!/bin/bash +# $Id: ip_create_tap 873 2017-04-14 11:56:29Z mueller $ +# +# Copyright 2017- by Walter F.J. Mueller +# License disclaimer see License.txt in $RETROBASE directory +# +# Revision History: +# Date Rev Version Comment +# 2017-04-14 873 1.0 Initial version +# 2017-03-04 858 0.5 First draft +# + +tap=${1:-tap0} + +if ifconfig | grep -q "${tap}\s*Link" +then + echo "tap ${tap} already exists" + exit 1 +fi + +ifconfig | grep -q "br0\s*Link" +if [ $? != 0 ] +then + echo "ip_create_tap-I: create bridge br0" + ip_create_br +fi + +# sanitize PATH, use what sudo has +export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +which_ifconfig=$(which ifconfig) +which_tunctl=$(which tunctl) +which_brctl=$(which brctl) + +if [[ -z "$which_ifconfig" || -z "$which_tunctl" || -z "$which_brctl" ]] +then + echo "ip_create_br-E: ifconfig, brctl, or route not in PATH" + exit 1 +fi + +# print info so that sudo password prompt is expected +if [[ $(id -u) -ne 0 ]] ; then echo "ip_create_br-I: requires sudo" ; fi + +sudo $which_tunctl -t ${tap} -u $USER +sudo $which_ifconfig ${tap} up +# bridge in the tap device +sudo $which_brctl addif br0 ${tap} +sudo $which_ifconfig ${tap} 0.0.0.0 + +# +$which_ifconfig ${tap} diff --git a/tools/bin/ip_inspect b/tools/bin/ip_inspect new file mode 100755 index 00000000..5c0bb452 --- /dev/null +++ b/tools/bin/ip_inspect @@ -0,0 +1,161 @@ +#!/usr/bin/perl -w +# $Id: ip_inspect 887 2017-04-28 19:32:52Z mueller $ +# +# Copyright 2017- by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, or at your option any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for complete details. +# +# Revision History: +# Date Rev Version Comment +# 2017-04-08 872 0.1 First draft +# + +use 5.14.0; # require Perl 5.14 or higher +use strict; # require strict checking + +use Getopt::Long; + +my %opts = (); + +GetOptions(\%opts, + ) + or exit 1; + +sub print_usage; +sub do_defeif; +sub do_addr4; +sub do_defroute; + +autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe + +my $cmd = shift @ARGV; +unless (defined $cmd) { + printf STDERR "ip_inspect-E: missing command; use 'ip_inspect help'\n"; + exit 1; +} + +if ($cmd eq "help") { + print_usage(); +} elsif ($cmd eq "defeif") { + do_defeif(); +} elsif ($cmd eq "addr4") { + do_addr4(); +} elsif ($cmd eq "defroute") { + do_defroute(); +} else { + printf STDERR "ip_inspect-E: invalid command '$cmd'\n"; + exit 1; +} +exit 0; + +#------------------------------------------------------------------------------- + +sub do_defeif { + my @devs; + open (IPRES, "ip link show|") or die "failed to call ip"; + while () { + chomp; + next unless m|^\d+:\s*(\w+):|; + my $dev = $1; + next unless $dev =~ m/^(en|eth)/; + push @devs,$dev; + } + close (IPRES); + if (scalar(@devs) == 0) { + printf STDERR "ip_inspect-E: failed to detect default device\n"; + exit 1; + } + if (scalar(@devs) > 1) { + printf STDERR "ip_inspect-E: multiple ethernet interfaces '%s'\n", + join ',',@devs; + exit 1; + } + print "$devs[0]\n"; + return; +} + +#------------------------------------------------------------------------------- + +sub do_addr4 { + my $dev = shift @ARGV; + my $fld = shift @ARGV; + unless (defined $dev && defined $fld) { + printf STDERR "ip_inspect-E: missing device or field\n"; + exit 1; + } + + my $addr; + my $size; + my $bcast; + open (IPRES, "ip addr show dev $dev|") or die "failed to call ip"; + while () { + chomp; + next unless m|^\s+inet\s+([0-9.]+)/(\d+)\s+brd\s+([0-9.]+)|; + $addr = $1; + $size = $2; + $bcast = $3; + } + close (IPRES); + if ($fld eq "addr") { + print "$addr\n"; + } elsif ($fld eq "addrm") { + print "$addr/$size\n"; + } elsif ($fld eq "mask") { + my $mask = size2mask($size); + print "$mask\n"; + } elsif ($fld eq "bcast") { + print "$bcast\n"; + } else { + printf STDERR "ip_inspect-E: invalid field '$fld'\n"; + exit 1; + } + return; +} + +#------------------------------------------------------------------------------- + +sub do_defroute { + open (IPRES, "ip route show|") or die "failed to call ip"; + while () { + chomp; + if (m|^default via\s+([0-9.]+)|) { + close (IPRES); + print "$1\n"; + return; + } + } + printf STDERR "ip_inspect-E: failed to find default route\n"; + exit 1; +} + +#------------------------------------------------------------------------------- + +sub size2mask { + my ($size) = @_; + my $bmask = ('1' x $size) . ('0' x (32-$size)); + my $dmask = oct("0b".substr($bmask, 0,8)) . '.' . + oct("0b".substr($bmask, 8,8)) . '.' . + oct("0b".substr($bmask,16,8)) . '.' . + oct("0b".substr($bmask,24,8)); + return $dmask; +} + +#------------------------------------------------------------------------------- + +sub print_usage { + print "usage: ip_inspect \n"; + print " ip_inspect defeif # get default eth interface\n"; + print " ip_inspect addr4 addrm # get ip4 addr/mask\n"; + print " ip_inspect addr4 addr # get ip4 bare addr\n"; + print " ip_inspect addr4 mask # get ip4 subnet mask\n"; + print " ip_inspect addr4 bcast # get ip4 bcast addr\n"; + print " ip_inspect defroute # get default route\n"; + return; +} diff --git a/tools/man/man1/ip_create_br.1 b/tools/man/man1/ip_create_br.1 new file mode 100644 index 00000000..3c6ec9a4 --- /dev/null +++ b/tools/man/man1/ip_create_br.1 @@ -0,0 +1,42 @@ +.\" -*- nroff -*- +.\" $Id: ip_create_br.1 893 2017-05-05 17:43:53Z mueller $ +.\" +.\" Copyright 2017- by Walter F.J. Mueller +.\" +.\" ------------------------------------------------------------------ +. +.TH IP_CREATE_BR 1 2017-04-14 "Retro Project" "Retro Project Manual" +.\" ------------------------------------------------------------------ +.SH NAME +ip_create_br \- create bridge and re-connect ethernet interface +.\" ------------------------------------------------------------------ +.SH SYNOPSIS +. +.SY ip_create_br +.YS +. +.\" ------------------------------------------------------------------ +.SH DESCRIPTION + +This script expects a default single Ethernet interface setup, creates +a bridge named 'br0', and re-connects Ethernet interface to this bridge. + +The scripts bails out gracefully in case 'br0' already exists. In not, it +determines the name of the Ethernet interface, accepting both old 'eth*' and +new 'en*' naming, and verifies that it is a single Ethernet configuration. +Than it creates a bridge device named 'br0' and re-connects the physical +Ethernet interface to the bridge, preserving all IP addresses and routes. + +This script is part of setting up tap devices with \fBip_create_tap\fR(1) +but can be used independently. + +The script should be started as normal user, but uses \fBsudo\fR(8) to +execute priviledged commands and might therefore ask for the user password. +. +.\" ------------------------------------------------------------------ +.SH "SEE ALSO" +.BR ip_create_tap (1) + +.\" ------------------------------------------------------------------ +.SH AUTHOR +Walter F.J. Mueller diff --git a/tools/man/man1/ip_create_tap.1 b/tools/man/man1/ip_create_tap.1 new file mode 100644 index 00000000..54e2d04e --- /dev/null +++ b/tools/man/man1/ip_create_tap.1 @@ -0,0 +1,40 @@ +.\" -*- nroff -*- +.\" $Id: ip_create_tap.1 893 2017-05-05 17:43:53Z mueller $ +.\" +.\" Copyright 2017- by Walter F.J. Mueller +.\" +.\" ------------------------------------------------------------------ +. +.TH IP_CREATE_TAP 1 2017-04-14 "Retro Project" "Retro Project Manual" +.\" ------------------------------------------------------------------ +.SH NAME +ip_create_tap \- add a user-mode tap device to a bridge +.\" ------------------------------------------------------------------ +.SH SYNOPSIS +. +.SY ip_create_tap +.RI [ TAPNAME ] +.YS +. +.\" ------------------------------------------------------------------ +.SH DESCRIPTION + +This script adds user-mode a tap device to a bridge, and creates the bridge +in case it doesn't exist already. + +The script first checks whether 'br0' exists, if not \fBip_create_br\fR(1) +is executed. Than a tap device is created, named \fITAPNAME\fP or 'tap0' +by default. The tap device will be accessible for the user which executes +the script. Finally the created tap device is connected to bridge 'br0'. + +The script should be started as normal user, but uses \fBsudo\fR(8) to +execute priviledged commands and might therefore ask for the user password. + +. +.\" ------------------------------------------------------------------ +.SH "SEE ALSO" +.BR ip_create_br (1) + +.\" ------------------------------------------------------------------ +.SH AUTHOR +Walter F.J. Mueller