Dual-path routing with Quagga


Well, I guess it took me long enough, but as promised, how I setup dual-path routing with Quagga. But first, thanks and credit to Colin and Jonathan for helping me out with this on IRC; as they had done similar work before, it was a lot easier than blazing the trail myself.

So, what the heck am I talking about? Let’s start off with a little background for those of you unfamiliar with the state of ADSL internet access in South Africa. Aside from the costs paid to the local telecommunications monopoly for the physical service provision, there is also an ISP charge for actually getting onto the internet, which includes charging for bandwidth usage (throughput). Exact pricing varies slightly between ISPs, but is mostly the same across the board, so I’ll quote prices from the ISP I use. To cut a long story short, I pay about R70 (US$9.46) per GB of international transfer (in both directions), but I can get local-only connectivity at a much cheaper rate of around R4.33 (US$0.59) per GB. This clearly makes it economically advantageous to do local transfers over a local-only account.

So, how to do it? My internet gateway, elvandar, is naturally running Debian GNU/Linux, so this can easily be setup. Please note that the following instructions are primarily designed for a Debian system, and your mileage may vary with other distributions.

  1. Configure your PPP connections appropriately.

    Make a copy of your existing /etc/peers/$PROVIDER file for the second PPP connection; you will want to change the username setting in the new file, and also remove the defaultroute setting, so that the default route will always point at the first PPP connection.. Next, add a unit 0 setting to the first file, and a unit unit 1 setting to the second (assuming you don’t already have these or similar); this ensures that the ppp0 and ppp1 devices (respectively) will always be used, rather than the order of the connections coming up determining how devices are assigned.

    For reference, my peer files are called saix and is, and I have the following stanzas in /etc/network/interfaces to bring them up:

    auto dsl
    iface dsl inet ppp
        provider saix
    auto dsl-is
    iface dsl-is inet ppp
        provider is
  2. Install Quagga.

    # aptitude install quagga

  3. Configure Quagga.

    My configuration looks like the following:

    hostname elvandar
    ### TENET
    # UCT-C1
    ip route      ppp1
    ### IS
    # ISNET-03
    ip route      ppp1
    ### Verizon
    # HC1-20050912
    ip route     ppp1
    ip route    ppp1
    ip route    ppp1
    ### Datapro
    # GIA-BLK6
    ip route    ppp1

    Initially I had plans to retrieve a list of local routes from public-route-server.is.co.za and use that, but I discovered that I was tweaking my routing a lot, so I decided to just stick with setting specific routes for hosts that I wanted them for.

  4. Enable the Zebra daemon.

    Edit /etc/quagga/daemons and set zebra=yes.

  5. Make sure the configuration changes take effect.

    # invoke-rc.d quagga force-reload

And there you have it. Zebra will automatically add the routes as the appropriate interface(s) come up, thus you don’t need to worry about the routes persisting across reconnections etc. (which is a good thing, since currently all ADSL connections are terminated after they have been active for 24 hours… argh!)

The Web


This is, without a doubt, the most awesome thing I have seen this week.

Also, my blog post on dual-path routing is still coming; stay tuned…

Clock drift


A post on python-dev by Neil McLaren caught my eye today:

A signal sent while the operating system is doing certain things to

the application (including, sometimes, when it is swapped out or

deep in I/O.)

That sounds like an outright bug. I can’t think

of any earthly reason why the handler shouldn’t

be called eventually, if it remains installed and

the process lives long enough.

See above. It gets lost at a low level. That is why you can cause

serious time drift on an “IBM PC” (most modern ones) by hammering

the video card or generating streams of floating-point fixups. Most

people don’t notice, because xntp or equivalent fixes it up.

Neil McLaren

If you’ve been wondering why the clock drift on your PC seems so

bad, perhaps this is part of the problem?

In my next blog post, I intend to detail setting up dual-path

routing to take advantage of the peculiarities of the South African ISP

market to save yourself some money if you are using an ADSL


The Xbox 360 saga


I purchased an Xbox 360 console a few months ago. At some point after I bought it, the unit seems to have developed some kind of fault; it scratches discs that I play in it. Initially I thought it might just have been incidental damage from having the discs lying around or whatever (although I’ve treated my game discs with the same care that I treat all of my optical media), but about two weeks ago, I took out my brand new Gears of War disc, checked it for scratches (the disc surface was pristine), then put it in the drive. Upon going into the game and trying to start the single-player campaign, I got a disc read error; sure enough, there were now several familiar-looking scratches on the surface.

Now convinced that it was, in fact, the unit, I e-mailed Microsoft Xbox 360 support. After receiving no reply after a day or two, I looked around and found the South Africa support number (a toll-free number), and called them; the person I spoke to was polite, but after giving them my details and then explaining my problem, they asked where I was phoning from. I replied “South Africa”, and was then told that they “don’t support South Africa”, and told to contact the retailer I purchased the console from. Huh? As it turns out, I did get an e-mail reply telling me to contact the callcenter on the number I found off the website, so that was also a dead loss.

So, ok, fair enough; the console was purchased at Look & Listen, so I I filled out the contact form on their website. Another day or two went by, with no response, so I scrounged up a phone number (the only phone number on their website is for M-WEB Business Technical Support!) from the Yellow Pages and gave them a call. After being put in contact with the person at that branch that handles their Games division, I explained the problem to him. He then asked me to contact the distributors (MI Digital) to confirm that they would authorize the replacement, and gave me the contact number. (I have yet to receive any e-mail reply to my message sent via the contact form on the website.)

On to the distributors; I spoke to a woman at MI Digital who asked me if I’d contacted Microsoft Support, and then mentioned that everyone was getting this “do not support South Africa” response, and that they were trying to kick Microsoft into getting their act together. I briefly described the situation, and she said that the retailer could fax through the proof of purchase and they would then give them the authorization number for the replacement.

Back to Look & Listen; I spoke to the same person as before, who sounded a bit sceptical about getting the replacement authorization, and said that he would contact the distributors directly just to sort everything out. He phoned me back a little while later, and it seems that they now wanted me to bring the unit in to check it out, due to the nature of the described problem.

A little aside here: there is a well-known problem with the Xbox 360 that occurs when rotating the unit while the disc is in use; the centrifigual force causes the disc to scrape against some or other metal edge in the unit, causing damage to the disc surface. However, from what I’ve seen, the scratch would always be in the same position relative to the edge of the disc, and looks quite different to the damage I was observing. Furthermore, my unit is on a level stable surface, and I did not touch the unit while the disc was in use.

Anyhow, I drove out to MI Digital’s offices, which are in Bedfordview; I live in Bryanston. Argh! On arriving, I endured a brief wait at reception before someone came to assist me. After relating the whole situation to him, he mentioned that the only known problem with disc scratching was the other problem I described in the previous paragraph; he agreed with me that it didn’t sound like that was what was happening in my case, but that he would need to try and reproduce the problem so that he could see it with his own eyes, and then go back to Microsoft with that, in order to do the replacement. A brief attempt to get the problem to happen right then and there was unsuccessful, so I ended up leaving the unit with them for more extended abuse; they were going to leave the unit running, play games on it, etc. for a few days to see if the problem would show up.

I received a call back from them earlier this afternoon; apparently they had been unable to reproduce the problem, but they were going to replace the unit anyway, along with the MS games, and he had even contacted the distributors about the one non-MS game (Splinter Cell: Double Agent) that I had left with them!

In short, kudos to MI Digital and Look & Listen. However, Look & Listen’s web designers (M-WEB Business, I suspect) and Microsoft Support need to get their act together.

UPDATE: minor style tweaks.

MSN Messenger


For those of you that haven’t seen this (and yes, it’s real):

Screenshot of an MSN Messenger window that has been customized to insane levels.

UPDATE: added image dimensions (hi Zelphar!), blurred out bits to protect the guilty.

Programming Wisdom


Quote of the day, from IRC:

 “Being a programmer means knowing how to write an ‘if’

             statement. Being a master programmer is knowing where to put it.”

 dash: I like this second sentence better: “Being a master

                programmer means knowing how not to.”

In other news, I’m still waiting for ADSL to be installed. I’ve also had conversations on IRC that will hopefully seed two more meaningful and contentful blog posts about information flow management, and the human mind; watch this space…



Just a quick post while it’s still September in UTC.

For those of you who don’t know (is there actually anyone reading my blog that doesn’t keep up with me on IRC / XMPP?), I’m currently in the process of moving into my own place. Telkom have tentatively scheduled my phone/DSL line installation for October 27, so until then I’ll probably be stuck on GPRS; what a nightmare…

On a different note, here’s one of my favourite quotes ever (I won’t spoil the fun by providing an attribution, STFW etc.):

I am the ineffable concept that unifies both deliberate

goal-oriented creation (interaction design) and deliberate

goal-oriented perpetual creation (dissent). In some deep way,

dissent and design are one. And I am that.

If I should fail in my aims then nobody else will achieve

anything of note, ever.



GoDaddy are not exactly the nicest registrar around; their site and e-mail newsletters are filled with annoying advertising/marketing junk, and their web interface is not particularly pleasant to use. However, they are relatively functional, and their prices are good, so you might have landed up registering a domain with them. At this point, if you are like me, you will want to follow best practices and setup an in-bailiwick delegation for your shiny new domain. Unfortunately, the exact procedure for doing this through GoDaddy’s web interface is not particularly obvious. For .com/.net/etc. domains, you need to register your nameservers in whois first; once you have done that, you can then list those nameservers for your domain.

Here is a step-by-step description of how to achieve this via the GoDaddy web interface:

  1. Log into the GoDaddy site.
  2. Select “My Account” in the sidebar on the right.
  3. Select “Manage Domains” underneath “Domain Names”.
  4. Select the domain you want to modify from the list (the domain name itself is a hyperlink).
  5. Expand “Domain Host Summary” in the sidebar on the right.
  6. Select “Click here to see details or to modify”.
  7. Fill in hostname / IP pairs (select “Add New Host” to get additional input controls if you have more than two nameservers), and then select “Save Changes” once you are done.
  8. Wait a minute or two, to allow the information to propagate to WHOIS.
  9. Select your domain from the list on the left, again.
  10. Select “Click here to see details or to modify.” under Nameservers summary in the sidebar.
  11. Fill in the hostnames of the nameservers you just configured, using “Add New Nameserver” as necessary, and selecting “Save Changes” once you are finished.
  12. Sit back, relax, and wait for the DNS records to propagate.



So, Colin has been ranting and raving about Django and templating and such again; subsequently, I had a brief conversation on IRC with someone else about the subject, and figured I’d do a bit of a braindump into my blog.

Like Colin, I have a strong dislike of using plaintext templating mechanisms for generating anything other than text/plain data. This is primarily due to the mixing of levels that this kind of usage entails; it is a design flaw very similar to the kind of design flaw that enables SQL injection attacks in poorly written applications. Your data should be filtering through a higher level abstraction which is then serialized by code specifically written to implement the output format; dumping it straight into a plaintext template is just begging for trouble, in the form of random garbage not conforming to the expected format. One only needs to look at all the malformed RSS feeds out there to see an example of how bad this can get.

However, there’s more to it; for example, templating systems like TAL are not plaintext, but are still problematic. The second problem is an issue of programming languages; in a typical webdev project I’m already writing Python code, JavaScript code, and maybe SQL code; writing yet more code in some relatively half-baked and featureless language is not an appealing concept. In addition, even if the business logic is separated out from the template, you still have presentation logic mingled with the actual template content; this may seem superficially attractive, but ultimately I find it to be counterproductive.

At this point, Colin and I have a divergence of opinion; while he prefers to make heavy use of stan (a somewhat “hackish” Nevow feature that allows you to write XML using Python syntax), I prefer to almost completely avoid it. To put it simply, I want to write Python code in my Python source files, JavaScript code in my JS source files, SQL code in SQL source files, XML in XML files, and CSS in CSS files. Given that all of these formats/tools allow me to do just that, I would rather avoid embedding copious amounts of one language in another, as I find working with JS embedded in Python (or whatever) to be more awkward and confusing than having it separated out.

I do think that using plaintext templating for emitting more structured data has its place in things like wikiish systems (eg. JotSpot) or CMSish systems, as an enabling technology for people who are nominally non-programmers; but for a “real” programmer with a full array of libraries and language at their disposal, it seems to just be bad system design.

In closing, I’ll note that I use Nevow for (X)HTML templating, making heavy use of patterns and templates, with a few render specials. If you’re not familiar with Nevow, that probably sounds like complete Greek; I suggest you do some more reading to get an idea of how Nevow templates work, but in very broad terms a pattern is an XML element marked with a nevow:pattern=”name” element; the element is then not directly present in the output, but is available to the presentation code, and is usually used for making N copies of a particular element structure. A slot, on the other hand, is a element, which is “filled” by the presentation code; that is, replaced with content supplied at render time.



This post is mainly a reaction to commentry on a post by Colin, as well as a parting shot delivered by Gavin.

I choose not to vote. This decision is something I’ve had many years to think about, not just a product of a flippant don’t-care-whatever attitude, which is why I’m actually bothering to blog about it. There are three main reasons behind this decision:

Firstly, who on earth is there to vote for? The ANC already have the majority of the vote; they might not be doing a particularly bad job, but I can hardly say I want to actually *support* them either. The DA’s platform is based around blindly opposing the ANC no matter what the issue at hand is, and making promises about service delivery that are even more absurd and unkeepable than the ANC’s. The ID are great at posturing too, but they don’t seem capable of doing anything more than running around barking. And the rest have insignificant support, and nothing particularly interesting either; half of them seem to be pushing some religious or racialist agenda that I want absolutely nothing to do with anyway. I’ll also note here that while I do not have any ability to vote in elections not occurring in South Africa, I have yet to see any country that is particularly different in this regard; the party names and particular details change, but the end result is still more-or-less the same.

Secondly, yes, I am not a supporter of “democracy”. Actually, South Africa (like everywhere else that claims “democracy”) has a system more along the lines of “representative democracy”, where you only make one democratic decision every N years. “Democracy” should more correctly refer to a system where all government decisions (or all major ones, anyway) involve a universal democratic voting process. Of course, the logistics of such a system already make it infeasible — but more importantly, for most matters, the majority of people would be completely unqualified to make any decisions one way or the other, so the result would likely be an even worse disaster. Semantic quibbling aside, I consider this kind of “democracy” (henceforth used without scare quotes) to be one of the greatest evils in the world today (due to its prevelancy, not magnitude); by voting, I am giving legitimacy to it, and becoming part of the problem. Contrary to popular opinion, voting is not the only way to go about affecting political change; it is not even the most effective way to do it.

Thirdly, my vote doesn’t count. That’s right, it doesn’t count. Neither does yours. Neither does any other individual’s vote. A single vote out of thousands or millions is simply not empowered to have any meaningful effect on the outcome. The units that *are* empowered to have such an effect are the larger groups in play; the larger a group, the more empowered it is to affect the outcome. This is the grim reality of democracy. The odds of a deadlock that only my vote will break occurring are infinitesmal; you’d have better luck winning enough money on the lottery to buy the vote out.

Ingrid asserts that government is suppose to be expressing *you*; and that’s a great fantasy. In reality, however, a democratically elected government can only express one group of people, even theoretically. In theory, they are meant to express the largest group; in practice, they claim to express all sorts of things, but ultimately express only their own desires and human flaws. This should come as no surprise, either: I’m not a perfect being, and slapping some political title in front of my name is not going to change that; why would it be different for any other human being?

With these factors in mind, I choose abstention as my participation in the “democratic process”. I would encourage other individuals to do the same; if enough people abstain from the vote, the illegitimacy of the democratic farce would be revealed for all to see. Of course, that’s not actually going to happen, because the group with the greatest voting power is also the least likely to vote intelligently, and no amount of voting by intelligent and/or educated people is going to change this.

This isn’t about shouting unvaluable comments from the peanut gallery; I provide commentary where I believe my words may have an effect by empowering others to make better-informed decisions about their actions.