From owner-svn-soc-all@freebsd.org Sun Jun 28 01:39:18 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4D26698C7A9 for ; Sun, 28 Jun 2015 01:39:18 +0000 (UTC) (envelope-from roam@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 32CF3129B for ; Sun, 28 Jun 2015 01:39:18 +0000 (UTC) (envelope-from roam@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id t5S1dIlf059327 for ; Sun, 28 Jun 2015 01:39:18 GMT (envelope-from roam@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t5S1dH5l059318 for svn-soc-all@FreeBSD.org; Sun, 28 Jun 2015 01:39:17 GMT (envelope-from roam@FreeBSD.org) Date: Sun, 28 Jun 2015 01:39:17 GMT Message-Id: <201506280139.t5S1dH5l059318@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to roam@FreeBSD.org using -f From: roam@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r287679 - soc2015/roam/ng_ayiya MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 28 Jun 2015 01:39:18 -0000 Author: roam Date: Sun Jun 28 01:39:16 2015 New Revision: 287679 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287679 Log: scaffold: configure two nodes back to back. Add the scaffold 'two' command and the Makefile 'two' target to configure two ng_ayiya nodes on lo0 aliases and let them talk to each other. Unfortunately, no IPv6 traffic may actually pass between them, at least for the present, since nothing can actually be forced to go "through" the interface :) ObQuote: "I am he as you are he as you are me and we are all together" Modified: soc2015/roam/ng_ayiya/Makefile soc2015/roam/ng_ayiya/scaffold.pl Modified: soc2015/roam/ng_ayiya/Makefile ============================================================================== --- soc2015/roam/ng_ayiya/Makefile Sat Jun 27 23:28:56 2015 (r287678) +++ soc2015/roam/ng_ayiya/Makefile Sun Jun 28 01:39:16 2015 (r287679) @@ -40,6 +40,9 @@ up: ${SCAFFOLD} setup +two: + ${SCAFFOLD} two + down: ${SCAFFOLD} shutdown Modified: soc2015/roam/ng_ayiya/scaffold.pl ============================================================================== --- soc2015/roam/ng_ayiya/scaffold.pl Sat Jun 27 23:28:56 2015 (r287678) +++ soc2015/roam/ng_ayiya/scaffold.pl Sun Jun 28 01:39:16 2015 (r287679) @@ -41,12 +41,16 @@ sub usage($); sub version(); -sub get_ayiya; +sub get_ayiya(;$); sub ngctl_list(); sub ngctl($ @); sub run_command(@); sub check_wait_result($ $ $); sub get_tic_tunnel($); +sub setup_node($ $); +sub setup_inet6($ $); +sub setup_ayiya($ $; $); +sub ensure_inet_aliases($ @); sub cmd_help($ @); sub cmd_setup($ @); @@ -54,6 +58,7 @@ sub cmd_status($ @); sub cmd_version($ @); sub cmd_inet6($ @); +sub cmd_two($ @); my %cmds = ( ayiya => \&cmd_ayiya, @@ -64,6 +69,7 @@ setup => \&cmd_setup, shutdown => \&cmd_shutdown, teardown => \&cmd_shutdown, + two => \&cmd_two, status => \&cmd_status, version => \&cmd_version, ); @@ -99,6 +105,7 @@ scaffold [-v] setup scaffold [-v] shutdown [all] scaffold [-v] status + scaffold [-v] two scaffold -V | -h -h display program usage information and exit @@ -185,13 +192,11 @@ sub shutdown_node($) { my ($node) = @_; - my $i6 = $node->{config}->{hooks}->{inet6}; - if (defined $i6) { - ngctl 'shutdown', "[$i6->{id}]:"; + for (grep defined, @{$node->{config}->{hooks}}{qw/ayiya inet6/}) { + ngctl 'shutdown', "[$_->{id}]:"; } ngctl 'shutdown', "[$node->{id}]:"; - # TODO: the ksocket one, too } sub cmd_shutdown($ @) @@ -250,31 +255,7 @@ my $ay = get_ayiya; if (!$ay->{ours}) { - my %found = map { ($_->{id}, 1) } @{$ay->{all}}; - - debug "Creating a new AYIYA node"; - ngctl 'mkpeer', 'ayiya', 'a', 'control/create'; - $ay = get_ayiya; - my @new = map $_->{id}, @{$ay->{all}}; - debug "Looking for an ID in (".join(' ', sort @new). - ") that's not in (".join(' ', sort keys %found).")"; - my $id; - for (@new) { - if (!defined $found{$_}) { - $id = $_; - last; - } - } - if (!defined $id) { - die "Internal error: no new AYIYA nodes\n"; - } - debug "- found $id"; - ngctl 'name', "[$id]:", 'sc_ayiya'; - $ay = get_ayiya; - if (!$ay->{ours} || $ay->{ours}->{id} ne $id) { - die "Internal error: get_ayiya() did not recognize ". - "node [$id] as ours\n"; - } + $ay = setup_node $ay, ''; } else { debug "Our node already there"; } @@ -284,15 +265,50 @@ "[$ay->{ours}->{id}] $ay->{ours}->{name}"; } -sub get_ayiya() +sub setup_node($ $) +{ + my ($ay, $suffix) = @_; + + my %found = map { ($_->{id}, 1) } @{$ay->{all}}; + + debug "Creating a new AYIYA node"; + ngctl 'mkpeer', 'ayiya', 'a', 'control/create'; + $ay = get_ayiya $suffix; + my @new = map $_->{id}, @{$ay->{all}}; + debug "Looking for an ID in (".join(' ', sort @new). + ") that's not in (".join(' ', sort keys %found).")"; + my $id; + for (@new) { + if (!defined $found{$_}) { + $id = $_; + last; + } + } + if (!defined $id) { + die "Internal error: no new AYIYA nodes\n"; + } + debug "- found $id"; + ngctl 'name', "[$id]:", "sc_ayiya$suffix"; + $ay = get_ayiya $suffix; + if (!$ay->{ours} || $ay->{ours}->{id} ne $id) { + die "Internal error: get_ayiya() did not recognize ". + "node [$id] as ours\n"; + } + return $ay; +} + +sub get_ayiya(;$) { + my ($suffix) = @_; + $suffix //= ''; + my $nodes = ngctl_list; my $res = { all => $nodes->{type}{ayiya} // [], ours => undef, others => [], }; - my $nm = 'sc_ayiya'; + my $nm = "sc_ayiya$suffix"; debug "Got ".scalar(@{$res->{all}})." AYIYA node(s), looking for $nm"; for my $node (@{$res->{all}}) { my $name = "[$node->{id}] '$node->{name}'"; @@ -393,11 +409,16 @@ 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; + setup_inet6 '', get_tic_tunnel shift @args; + # FIXME: Add a default route here, too. +} +sub setup_inet6($ $) +{ + my ($suffix, $t) = @_; + + my $ayiya = get_ayiya $suffix; if (!$ayiya->{ours}) { die "Our ng_ayiya node is not configured\n"; } @@ -410,16 +431,15 @@ } # OK, let's create one - my $hkname = "inet6/$tunnel"; + my $hkname = 'inet6/'.$t->id; ngctl 'mkpeer', "$c->{name}:", 'iface', $hkname, 'inet6'; - $ayiya = get_ayiya; + $ayiya = get_ayiya $suffix; 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($) @@ -463,11 +483,15 @@ warn "The ayiya command expects a tunnel name parameter\n"; usage 1; } - my $tunnel = shift @args; - my $t = get_tic_tunnel $tunnel; - my $ayiya = get_ayiya; + setup_ayiya '', get_tic_tunnel shift @args; +} + +sub setup_ayiya($ $; $) +{ + my ($suffix, $t, $localaddr) = @_; + my $ayiya = get_ayiya $suffix; if (!$ayiya->{ours}) { die "Our ng_ayiya node is not configured\n"; } @@ -485,18 +509,99 @@ $p = "[ $p ]"; ngctl 'msg', "$c->{name}:", 'secrethash', $p; # OK, let's create one - my $hkname = "ayiya/$tunnel"; + my $hkname = 'ayiya/'.$t->id; my $hkpeer = 'inet/dgram/udp'; - my $pname = 'sc_conn'; + my $pname = "sc_conn$suffix"; ngctl 'mkpeer', "$c->{name}:", 'ksocket', $hkname, $hkpeer; ngctl 'name', "$c->{name}:$hkname", $pname; - $ayiya = get_ayiya; + $ayiya = get_ayiya $suffix; $c = $ayiya->{ours}->{config}; if (!defined $c || $c->{hooks}->{ayiya}->{name} ne $pname) { die "Could not query the newly-created ng_ksocket node\n"; } + if (defined $localaddr) { + ngctl 'msg', "$pname:", 'bind', "inet/$localaddr:5072"; + } ngctl 'msg', "$pname:", 'connect', 'inet/'.$t->ipv4_pop.':5072'; debug "Trying to get the node to configure itself"; ngctl 'msg', "$c->{name}:", 'configure'; } + +sub cmd_two($ @) +{ + my ($cmd, @args) = @_; + + if (@args) { + say STDERR "The 'two' command does not need any arguments\n"; + usage 1; + } + + cmd_setup 'setup'; + + my $client = get_ayiya; + if (!$client->{ours}) { + die "Our ng_ayiya node is not configured\n"; + } + + my $server = get_ayiya '_s'; + if (!$server->{ours}) { + debug "Setting up the server node"; + $server = setup_node $server, '_s'; + debug "Got a server node: [$server->{ours}->{id}] ". + "'$server->{ours}->{name}'"; + } + + my ($client6, $server6) = ('fec0::1', 'fec0::2'); + my ($client4, $server4) = ('127.0.13.1', '127.0.13.2'); + ensure_inet_aliases 'lo0', $client4, $server4; + + my %defs = ( + TunnelId => 'T00001', + Password => 'secret', + Type => 'AYIYA', + ); + my $cli_tun = Net::SixXS::Data::Tunnel->from_hash({ + %defs, + 'IPv6 Endpoint' => $client6, + 'IPv6 POP' => $server6, + 'IPv4 POP' => $server4, + }); + my $srv_tun = Net::SixXS::Data::Tunnel->from_hash({ + %defs, + 'IPv6 Endpoint' => $server6, + 'IPv6 POP' => $client6, + 'IPv4 POP' => $client4, + }); + + setup_inet6 '', $cli_tun; + setup_inet6 '_s', $srv_tun; + + setup_ayiya '', $cli_tun, $client4; + setup_ayiya '_s', $srv_tun, $server4; +} + +sub ensure_inet_aliases($ @) +{ + my ($iface, @addresses) = @_; + + my $all = 1; + my $config = run_command 'ifconfig', $iface; + for my $addr (@addresses) { + debug "Checking $iface for $addr"; + if (index($config, $addr) == -1) { + undef $all; + debug "- nope, trying to bring it up"; + run_command 'ifconfig', $iface, 'inet', $addr, + 'netmask', '0xffffffff', 'alias'; + } + } + return if $all; + + # Now check... + $config = run_command 'ifconfig', $iface; + my @missing = grep { index($config, $_) == -1 } @addresses; + if (@missing) { + die "Could not bring up @missing on $iface\n"; + } +}