Abbie “Mini Mew” (2003 – June 10, 2011)

This is Abbie, but I always nickname them, so hers was “Mini Mew”. Yesterday she was put to sleep after treatment for kidney failure and ultimately complete failure. Here’s a few pictures I had of her. Unfortunately she liked to hide a lot and after I moved out of my parent’s house I only saw her during rare moments of not hiding under a bed or something.

ninjamonkey.us

ninjamonkey.us

ninjamonkey.us

ninjamonkey.us

ninjamonkey.us

She eventually ended up back at the vet a few days ago and we found out she was dying. It was only a matter of time or she’d be put to sleep. Some final tests were run and the decision ended up being the latter. I visited her at the vet to say goodbye the day before and took a few pictures and videos of her rubbing my hand. When I came into the room she was sitting in the litter box her her cage. She meowed at me once – the only time I can clearly recall her doing so as she was normally a quiet cat – and came out to rub my hand and lick at a plate of food. She hadn’t been eating for days and was rapidly losing weight and dehydrated.

ninjamonkey.us

And then the final morning came. All of us who were able to came to the vet’s office to be with her one last time. She was a blanket, but she would get up, circle, and rub her head on everyone’s hands. She would try to roll on her back but it was clear she was tired. And after about 10 minutes of saying goodbye in her own way, she just curled up as if to go to sleep.

ninjamonkey.us

I held her head and took this final picture and we called in the vet. I stroked her side during the procedure. She went quickly, faster than I thought, I didn’t even notice when she left us. She left this world being held by those who loved and cared for her. Mini mew came to us in 2003 after the passing of my cat Glendale and left us too soon on June 10, 2011. She will be buried in my parent’s back yard with the other cats on Monday.

Goodbye, mini mew, we’ll miss you.

IPv6 with the HP AP420

I use an HP AP420 wireless access point at the office and a few other locations. Although certainly not as cheap as a low end Linksys, they’re probably some of the most reliable ones I’ve used and can be found on eBay these days for a great price.

I did have one problem: it didn’t seem to be passing IPv6 router advertisements (RA) and thus autoconfig would not work. I finally discovered the culprit today: the “AP Management Filter” must be set to “disabled”. With it enabled it was apparently filtering IPv6 RAs. Since I am using a management VLAN this setting was pointless in my environment, but I thought I should document this potentially obscure problem in case anyone else happens across it.

Installing hp-snmp-agents on Debian 6.0 “squeeze”

I was installing the hp-snmp-agents package for a new server on a freshly installed Debian 6.0 “squeeze” server when it threw this error:

Setting up hp-snmp-agents (8.5.0.1.1-2) ...
insserv: Service snmp has to be enabled to start service hp-snmp-agents
insserv: exiting now!
update-rc.d: error: insserv rejected the script header

Uh oh, it looks like there’s a problem with the dependency based boot support. But wait, there’s an easy way to fix this! (There are some blogs out there indicating an incorrect workaround, but I won’t repeat it here.) The init script for hp-snmp-agents has a minor error in it: the SNMP daemon Required-Start dependency needs to be changed from “snmp” to “snmpd” for Debian. Here’s a diff:

--- /etc/init.d/hp-snmp-agents.orig 2011-02-10 12:43:44.394801490 -0800
+++ /etc/init.d/hp-snmp-agents 2011-02-10 12:44:01.402801357 -0800
@@ -10,7 +10,7 @@
# Following lines are in conformance with LSB 1.2 spec
### BEGIN INIT INFO
# Provides: hp-snmp-agents
-# Required-Start: hp-health snmp
+# Required-Start: hp-health snmpd
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6

Ignoring the fact that my clock wasn’t set yet, simply correct the Required-Start line and you’re good to go. Plus, by fixing this the right way, you’ve preserved the dependency based boot functionality as was originally intended by the init script’s inclusion of those lines.

IPv6 Milestone

Just this last week I finally converted my last IPv4-only transit into dual-stack. It’s long been a goal of mine to be 100% IPv6 native and it’s finally done.

Storing IPv6 Addresses in MySQL

Last year when I was searching for ways to overcome the lack of built-in IPv6 functions in MySQL, I was curious how other people were solving the problem. There are solutions out there that store IPv6 addresses across two database fields, but I find this unwieldy and prefer storing them as a single value. This was by far the most elegant solution I found that doesn’t rely on external dependencies (like writing special functions for your program to handle the two-value method):

http://oierud.name/bliki/IPv6AdressesAndMysql.html

Basically, it duplicates the capabilities of the built-in IPv4 INET_ATON() and INET_NTOA() counterparts. And case the URL ever goes dead:


INET_ATON6

DELIMITER //
CREATE FUNCTION INET_ATON6(n CHAR(39))
RETURNS DECIMAL(39) UNSIGNED
DETERMINISTIC
BEGIN
    RETURN CAST(CONV(SUBSTRING(n FROM  1 FOR 4), 16, 10) AS DECIMAL(39))
                       * 5192296858534827628530496329220096 -- 65536 ^ 7
         + CAST(CONV(SUBSTRING(n FROM  6 FOR 4), 16, 10) AS DECIMAL(39))
                       *      79228162514264337593543950336 -- 65536 ^ 6
         + CAST(CONV(SUBSTRING(n FROM 11 FOR 4), 16, 10) AS DECIMAL(39))
                       *          1208925819614629174706176 -- 65536 ^ 5
         + CAST(CONV(SUBSTRING(n FROM 16 FOR 4), 16, 10) AS DECIMAL(39)) 
                       *               18446744073709551616 -- 65536 ^ 4
         + CAST(CONV(SUBSTRING(n FROM 21 FOR 4), 16, 10) AS DECIMAL(39))
                       *                    281474976710656 -- 65536 ^ 3
         + CAST(CONV(SUBSTRING(n FROM 26 FOR 4), 16, 10) AS DECIMAL(39))
                       *                         4294967296 -- 65536 ^ 2
         + CAST(CONV(SUBSTRING(n FROM 31 FOR 4), 16, 10) AS DECIMAL(39))
                       *                              65536 -- 65536 ^ 1
         + CAST(CONV(SUBSTRING(n FROM 36 FOR 4), 16, 10) AS DECIMAL(39))
         ;
END;
//
DELIMITER ;

INET_NTOA6

DELIMITER //
CREATE FUNCTION INET_NTOA6(n DECIMAL(39) UNSIGNED)
RETURNS CHAR(39)
DETERMINISTIC
BEGIN
  DECLARE a CHAR(39)             DEFAULT '';
  DECLARE i INT                  DEFAULT 7;
  DECLARE q DECIMAL(39) UNSIGNED DEFAULT 0;
  DECLARE r INT                  DEFAULT 0;
  WHILE i DO
    -- DIV doesn't work with nubers > bigint
    SET q := FLOOR(n / 65536);
    SET r := n MOD 65536;
    SET n := q;
    SET a := CONCAT_WS(':', LPAD(CONV(r, 10, 16), 4, '0'), a);

    SET i := i - 1;
  END WHILE;

  SET a := TRIM(TRAILING ':' FROM CONCAT_WS(':',
                                            LPAD(CONV(n, 10, 16), 4, '0'),
                                            a));

  RETURN a;

END;
//
DELIMITER ;

Netflix on Roku Bandwidth

What watching a movie (Tears of the Sun) on Netflix via my Roku box looks like:

During a recent thread on NANOG, it was asserted that 2Mbps was sufficient for streaming, so I looked at my graphs to share my personal experience. The reported quality on the Roku was “four dots”. The scale is one to four dots then “HD”.

IPv6 Router Redundancy using RA

In the IPv4 world, router or gateway redundancy is accomplished using a protocol such as VRRP or HSRP. Many of these same routers support IPv6, but not the redundancy factor. Or do they? Fortunately in IPv6 land there’s a built-in feature in the protocol called “router advertisement”, or RA. A router with an IPv6 address on an interface will generate an RA for hosts on the same layer 2 segment. Using this feature, we can create a simple failover setup for IPv6 between two routers. In this example I’m using Cisco routers, but the same concept can be applied elsewhere.

The concept is extremely simple: configure the IPv6 address on both router interfaces as anycast (that is, disable duplicate address detection) and adjust the RA interval and lifetime parameters to your liking. The hosts will pick up the link local addresses from each router/gateway as a candidate default gateway. If one of them fails it will stop sending its respective RA.

The Cisco interface config commands to be applied to the router interfaces are:

ipv6 address 2001:0DB8:107:400::1/64 anycast
ipv6 nd ra-interval 60
ipv6 nd ra-lifetime 300

That’s it! Now you have a basic redundant IPv6 gateway. The obvious drawback to this is recovery time: the failed RA will have to time out on the hosts before it is removed from their routing table. However, you can adjust the RA lifetime on most platforms. This also requires that the hosts listen for RA (which may have implications on an end-user network such as rouge RA). The benefit is that in any case you’ll have simple redundancy using a protocol feature that you may otherwise not have.

Debian IPv6 Without Autoconf

You can’t disable autoconf in sysctl.conf because the ipv6 module hasn’t loaded yet, and the ipv6 module loads after /etc/network/interfaces is parsed (thus ignoring your inet6 static section), so here’s how to do static IPv6 addressing with Debian:

iface eth0 inet6 static
    address 2001:0DB8:107:400::a
    netmask 64
    pre-up modprobe ipv6
    pre-up echo 0 > /proc/sys/net/ipv6/conf/$IFACE/autoconf

The gateway will be picked up by listening for router advertisements, as this simply disables the autoconf address. This is ideal for servers.

Debian 6.0 “squeeze”

The IPv6 module no longer exists since it’s now built in (like IPv4), so just omit the modprobe line as such:

iface eth0 inet6 static
    address 2001:0DB8:107:400::a
    netmask 64
    pre-up echo 0 > /proc/sys/net/ipv6/conf/$IFACE/autoconf