IPv6 Temporary addresses to Queue target

I have done a search and haven’t found anything, but I thought I would check first before embarking on this little project.

Environment: Home 25Mbit/300Mbit with 38 devices (yes, 38…NAS(x2), managed switch, 3xAPs, speakers, ipads, iphones, TV’s, Macs, etc.) Peered/failover isc-dhcpd with all static reservations, bind9 DNS across 3 local NS.

Goal: I want to start using IPv6 on my hosts, I have this setup and working.

Issue: I keep a set of simple queues for my kiddos that keeps them from eating bandwidth and limits them based on time of day. I don’t want to turn off IPv6 privacy on the Mac’s, but that is the catch.

My current plan is to have a script walk through the queues (one per kid and their devices), pull out the IP addresses [/queue sim get "KidsQ- target], then go find the MAC in ARP table, then go walk IPv6 neighbors collecting up matching IPv6 addresses (minus fe80:) and add those to their queue.

The other that springs to mind would be by packet marking, but I’ve noted that conn + packet marking seems to slow down my throughput fairly significantly on my hex (drop of ~100Mbit D/L for non-queued clients)

Any thoughts?

Okay,

Solved:
Bad IP address in the address list (192.167.x.x vs. 192.168.x.x so there was no MAC to lookup. However, this did make me put in a (:len [/ip mac find address=$ladd]) if statement to check for an ARP table entry before looking for it to avoid the error and script termination.

I’ve set off on this adventure and have parts of it running. I’ve run into an issue and it’s with looking up mac-address in /ip arp. Neither of these seem to work from script, but work from command-line:

:local ladd [/ip fire add get $i address]; # this seems to work fine and returns the address I'm looking up.
:put "Got IP=[$ladd]"; # I use the brackets to look for extra spaces and the like
:set lmac [/ip arp get [/ip arp find address=$ladd] mac-address];
no such item

or

:set lmac  [/ip arp get [/ip arp find where address=$ladd] mac-address];
 no such item

Ok, well here is my v0.5 for anyone who is interested.

It comes in 2 parts, the main script which looks for the systems in /ip fire add list=“qsys” for IP addresses and the Queue they are related to in comment.
It goes and gets the MAC address (if it exists) from /ip arp table.
It then cross references that with a address-list kept in /ipv6 fire add list=“neigh” which is IPv6 + MAC in comment.
It then builds a queue target list based on this info and sets the targets for the queue named in the original /ip fire add list=“qsys” comment.

The second script just watches /ipv6 neighbors and write that to a /ipv6 fire add list=“neigh” because I’ve noted that the neighbor list seems to be very transient. This can probably be changed with a setting, but I’m not sure which one.

TODO:

  • Rework to be one script solution, both IPv6 neighbor discovery/logging and queue update.
    Only update the queue that has changes, based on above.


#
# IPv6 Neighbor2Queue
# 
# 17.07.09               v0.5                 RHS               Wrote it
#

:local nid;
:local qid;
:local lid;
:local ip6 "";
:local mac6 "";
:local qstring "";
:local debug 1;



:foreach i in=[/ip fire add find where list="qsys"] do={

  :local comm [/ip fire add get $i comment];
  :local lque [:pick $comm 0 [:find $comm " + "]];
  :set lque $comm;
  :local lmac;
  :local ladd [/ip fire add get $i address];
  :local tgt $ladd;

  :if ($debug > 0 ) do={ 

     :put "\n\rNext Item";  
     :put "IP addy [$ladd] comm=[$comm] lque=[$lque]" 

  }

  :local varif [/ip arp find address="$ladd"];
  :if ( [:len $varif] != 0 ) do={

    :set lmac [/ip arp get [/ip arp find address="$ladd"] mac-address];
    :if ($debug > 0 ) do={ :put "MAC for [$ladd] from ARP=[$lmac]" };

    :foreach lid in=[/ipv6 fire add find comment="$lmac"] do={
#      :put "here $lid";
      :local mip6 [/ipv6 fire add get $lid address];
      :local mmac [/ipv6 fire add get $lid comment];
#      :put "nid=[$lid] ip6=[$mip6] mac=[$mmac]";
      :set tgt ($tgt . "," . $mip6);
    }

#    :foreach nid in=[/ipv6 ne find where interface="ether2-lan" ] do={
#
#      :set ip6 [/ipv6 ne get $nid address];
#      :set mac6 [/ipv6 ne get $nid mac-address];
#      :if ( ($mac6 = $lmac ) and !($ip6 ~ "fe80") ) do={
#
#          :if ($debug > 7 ) do={ :put "Match! $ip6"; }
#          :set tgt ($tgt . "," . $ip6);

#        }
 #     }
    } else={ :if ($debug > 0) do={ :put "No MAC, Skipping lookup"}  }
   
    :if ( [:len [:find $qstring $lque]] > 0 ) do={

      :if ( $debug = 1) do={ :put "Found [$lque] in [$qstring]"; }

      :foreach x in=[/queue simple print as-value where name="$lque" ] do={
        :foreach j in=($x->"target") do={

           :if ($debug > 7 ) do={ :put "ADDY=[$j]" };
           :set tgt ( $tgt . "," . $j );

        }

      }

    } else={

      :if ($debug > 0) do={ :put "Not found, adding [$lque]"; }
      :set qstring ( $qstring . " " . $lque );

    }

:if ($debug > 0) do={ :put "EXEC: /queue sim set [find name=\"$lque\"] target=\"$tgt\""; }
/queue sim set [find name="$lque"] target="$tgt";


}