Date: Wed, 10 Jun 2015 21:03:47 GMT From: roam@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286925 - soc2015/roam/ng_ayiya Message-ID: <201506102103.t5AL3lNM005472@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: roam Date: Wed Jun 10 21:03:46 2015 New Revision: 286925 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286925 Log: Configure the ng_iface inet6 address. Use the tools from the brand-new Net-SixXS Perl distribution to parse the tunnel information obtained from TIC. Create a ng_iface node, connect to its "inet6" hook, and configure the local IPv6 address on it. That was the easy part :) ObQuote: "It's so easy when everybody tries to please me" Modified: soc2015/roam/ng_ayiya/Makefile soc2015/roam/ng_ayiya/scaffold.pl Modified: soc2015/roam/ng_ayiya/Makefile ============================================================================== --- soc2015/roam/ng_ayiya/Makefile Wed Jun 10 21:03:42 2015 (r286924) +++ soc2015/roam/ng_ayiya/Makefile Wed Jun 10 21:03:46 2015 (r286925) @@ -35,6 +35,8 @@ SCAFFOLD_V?= -v SCAFFOLD?= ${SUDO} ${PERL} ${SCAFFOLD_PL} ${SCAFFOLD_V} +TIC_TUNNEL?= T22928 + up: ${SCAFFOLD} setup @@ -43,3 +45,11 @@ down-all: ${SCAFFOLD} shutdown all + +tic-tunnels.txt: + @printf "\n\n======================\n\nPlease create the tic-tunnels.txt with the output of the sixxs-tic-tunnels tool\n\n======================\n\n" + false + +tic: tic-tunnels.txt + ${SCAFFOLD} inet6 ${TIC_TUNNEL} + ${SCAFFOLD} ayiya Modified: soc2015/roam/ng_ayiya/scaffold.pl ============================================================================== --- soc2015/roam/ng_ayiya/scaffold.pl Wed Jun 10 21:03:42 2015 (r286924) +++ soc2015/roam/ng_ayiya/scaffold.pl Wed Jun 10 21:03:46 2015 (r286925) @@ -30,6 +30,7 @@ use Getopt::Std; use JSON::PP; +use Net::SixXS::Data::Tunnel; use POSIX qw/:sys_wait_h/; my $debug = 0; @@ -44,17 +45,20 @@ sub ngctl($ @); sub run_command(@); sub check_wait_result($ $ $); +sub get_tic_tunnel($); sub cmd_help($ @); sub cmd_setup($ @); sub cmd_shutdown($ @); sub cmd_status($ @); sub cmd_version($ @); +sub cmd_inet6($ @); my %cmds = ( build => \&cmd_setup, erect => \&cmd_setup, help => \&cmd_help, + inet6 => \&cmd_inet6, setup => \&cmd_setup, shutdown => \&cmd_shutdown, teardown => \&cmd_shutdown, @@ -88,6 +92,7 @@ my ($err) = @_; my $s = <<EOUSAGE Usage: scaffold help + scaffold inet6 tunnelname scaffold [-v] setup scaffold [-v] shutdown [all] scaffold [-v] status @@ -268,32 +273,40 @@ { my $nodes = ngctl_list; my $res = { - all => $nodes->{type}{ayiya}, + all => $nodes->{type}{ayiya} // [], + ours => undef, + others => [], }; - my $node; - my @ay = @{$res->{all} // []}; - debug "Got ".scalar(@ay)." AYIYA node(s), looking for ours..."; - for(my $i = 0; $i < @ay; $i++) { - if ($ay[$i]->{name} eq 'sc_ayiya') { - debug "- found it at position $i"; - ($node) = splice @ay, $i, 1; - last; - } - } - $res->{ours} = $node; - $res->{others} = \@ay; - - if (defined $node) { - my $js = ngctl 'config', "$node->{name}:"; + my $nm = 'sc_ayiya'; + debug "Got ".scalar(@{$res->{all}})." AYIYA node(s), looking for $nm"; + for my $node (@{$res->{all}}) { + my $name = "[$node->{id}] '$node->{name}'"; + my $js = ngctl 'config', "[$node->{id}]:"; $js =~ s/\A[^{]*//s; - debug "- got ".length($js)." characters of JSON"; - my $d = decode_json $js; - if (!defined($d) || ref $d ne 'HASH' || + debug "- got ".length($js)." characters of JSON for node $name"; + my $d; + eval { + $d = decode_json $js; + }; + my $err = $@; + if (length ($err // '') || !defined($d) || ref $d ne 'HASH' || grep !exists $d->{$_}, qw/id name has_secret hooks/) { - die "Node [$node->{id}] '$node->{name}' returned ". + warn "Node [$node->{id}] '$node->{name}' returned ". "an invalid JSON configuration\n"; + next; + } + $node->{config} = $d; + if ($node->{name} eq $nm) { + if (defined $res->{ours}) { + die "Inconsistent Netgraph configuration: ". + "duplicate name '$nm' for nodes ". + "[$res->{ours}->{id}] and [$node->{id}]\n"; + } + $res->{ours} = $node; + debug " - ours!"; + } else { + push @{$res->{others}}, $node; } - debug "- got keys: ".join(' ', sort keys %{$d}); } return $res; } @@ -356,3 +369,73 @@ } return $output; } + +sub cmd_inet6($ @) +{ + my ($cmd, @args) = @_; + + if (@args != 1) { + warn "The inet6 command expects a tunnel name parameter\n"; + usage 1; + } + my $tunnel = shift @args; + + my $t = get_tic_tunnel $tunnel; + my $ayiya = get_ayiya; + + if (!$ayiya->{ours}) { + die "Our ng_ayiya node is not configured\n"; + } + # Tear down the interface if it's configured + my $c = $ayiya->{ours}->{config}; + my $i6 = $c->{hooks}->{inet6}; + if (defined $i6) { + debug "Shutting down the current interface"; + ngctl 'shutdown', "[$i6->{id}]:"; + } + + # OK, let's create one + my $hkname = "inet6/$tunnel"; + ngctl 'mkpeer', "$c->{name}:", 'iface', $hkname, 'inet6'; + $ayiya = get_ayiya; + my $iface = $ayiya->{ours}->{config}->{hooks}->{inet6}->{name}; + if (!defined $iface) { + die "Could not query the newly-created ng_iface node\n"; + } + + run_command 'ifconfig', $iface, 'inet6', $t->ipv6_local; + # FIXME: Add a default route here, too. +} + +sub get_tic_tunnel($) +{ + my ($tunnel) = @_; + + my $fname = 'tic-tunnels.txt'; + open my $f, '<', $fname or + die "Could not open $fname: $!\n"; + my $in; + my %cfg; + while (<$f>) { + s/[\r\n]*$//; + if ($in) { + last unless /^\s+(\S[^:]+?)\s*:\s*(.*?)\s*$/; + my ($k, $v) = ($1, $2); + if (exists $cfg{$k}) { + die "Duplicate key $k for $tunnel in $fname\n"; + } + $cfg{$k} = $v; + } elsif ($_ eq $tunnel) { + $in = 1; + } + } + close $f or die "Could not close $fname: $!\n"; + if (!%cfg) { + if ($in) { + die "No key/value lines for $tunnel in $fname\n"; + } else { + die "No tunnel $tunnel defined in $fname\n"; + } + } + return Net::SixXS::Data::Tunnel->from_hash(\%cfg); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506102103.t5AL3lNM005472>