liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

acquire-wan-address.fnl (2128B)


      1 (local { : merge : split : file-exists? : system } (require :anoia))
      2 (local svc (require :anoia.svc))
      3 
      4 ;; structurally this is remarkably similar to
      5 ;; acquire-lan-prefix.fnl. maybe they should be merged: if not then
      6 ;; we could at least extract some common code
      7 
      8 ;; (alternatively we could move all the parsing code into the thing in
      9 ;; the odhcp service that *writes* this stuff)
     10 
     11 ; (parse-address "2001:8b0:1111:1111:0:ffff:51bb:4cf2/128,3600,7200")
     12 
     13 
     14 (fn parse-address [str]
     15   (fn parse-extra [s]
     16     (let [out {}]
     17       (each [name val (string.gmatch s ",(.-)=([^,]+)")]
     18         (tset out name val))
     19       out))
     20   (let [(address len preferred valid extra)
     21         (string.match str "(.-)/(%d+),(%d+),(%d+)(.*)$")]
     22     (merge {: address : len : preferred : valid} (parse-extra extra))))
     23 
     24 (local bound-states
     25        { :bound true
     26          :rebound true
     27          :informed true
     28          :updated true
     29          :ra-updated true
     30          })
     31 
     32 (fn changes [old-addresses new-addresses]
     33   (let [added {}
     34         deleted {}
     35         old-set (collect [_ v (ipairs old-addresses)] (values v true))
     36         new-set (collect [_ v (ipairs new-addresses)] (values v true))]
     37     (each [_ address (ipairs new-addresses)]
     38       (if (not (. old-set address))
     39           (table.insert added (parse-address address))))
     40     (each [_ address (ipairs old-addresses)]
     41       (if (not (. new-set address))
     42           (table.insert deleted (parse-address address))))
     43     (values added deleted)))
     44 
     45 (let [[state-directory wan-device] arg
     46       dir (svc.open state-directory)]
     47   (var addresses [])
     48   (while true
     49     (while (not (dir:ready?)) (dir:wait))
     50     (if (. bound-states (dir:output "state"))
     51         (let [new-addresses (split " " (dir:output "/addresses"))
     52               (added deleted) (changes addresses new-addresses)]
     53           (each [_ p (ipairs added)]
     54             (system
     55              (.. "ip address add " p.address "/" p.len " dev " wan-device)))
     56           (each [_ p (ipairs deleted)]
     57             (system
     58              (.. "ip address del " p.address "/" p.len " dev " wan-device)))
     59     	  (set addresses new-addresses)))
     60     (dir:wait)))