[j-nsp] dhcpv6 IA_PD syslogging
Jared Mauch
jared at puck.nether.net
Wed Jul 10 12:32:29 EDT 2024
Here's my Juniper config:
dhcp-relay {
dhcpv6 {
overrides {
allow-snooped-clients;
}
relay-agent-option-79;
group FTTHCustomersv6 {
relay-agent-remote-id {
use-option-82;
}
interface irb.100;
interface irb.200;
}
relay-agent-interface-id {
use-option-82;
}
relay-agent-remote-id {
use-option-82;
keep-incoming-remote-id;
}
server-group {
FTTHCustomers6 {
2001:db8:db8:db8:db8:db8:db8:db8;
}
}
active-server-group FTTHCustomers6;
}
forward-snooped-clients configured-interfaces;
overrides {
trust-option-82;
bootp-support;
replace-ip-source-with giaddr;
}
server-group {
FTTHCustomers {
169.254.1.1;
169.254.2.2;
}
}
active-server-group FTTHCustomers;
group FTTHCustomers {
overrides {
trust-option-82;
bootp-support;
replace-ip-source-with giaddr;
}
interface xe-0/0/47.0;
interface irb.100;
interface irb.200;
}
}
On Wed, Jul 10, 2024 at 12:21:02PM -0400, Jared Mauch via juniper-nsp wrote:
> like this:
>
> subnet6 2001:db8:0003::/64 {
> # agent.link-address
>
> pool6 {
> range6 2001:db8:3::100 2001:db8:3::fff0;
> }
> option dhcp6.next-hop 2001:db8:0003::1;
> prefix6 2001:db8:3:0010:: 2001:db8:3:ff00:: /60;
>
>
> on commit {
> set agent_circuit-id = concat("", v6relay(1, option dhcp6.interface-id));
> log ( error, concat( "COMMIT6|Interface:", v6relay(1, option dhcp6.interface-id), "|", v6relay(1, option dhcp6.relay-id), "|", v6relay(1, option dhcp6.remote-id)));
> log ( error, concat( "HWADDR-DUID: ", v6relay(1, (binary-to-ascii(16, 8, ":", option dhcp6.client-linklayer-addr))), " is connected to ", binary-to-ascii(16, 8, ":", option dhcp6.client-id)));
> log (info, concat ("Lease6 for ", binary-to-ascii(16,16, ":", substring(suffix(option dhcp6.ia-na, 24),0,16)), " lease to ",v6relay(1, (binary-to-ascii(16, 8, ":", option dhcp6.client-linklayer-addr)))));
>
> if exists dhcp6.client-id { log(error, concat(" dhcp6.client-id = ", binary-to-ascii(16, 8, ":", v6relay(1, option dhcp6.client-id))));
> log(error, concat(" dhcp6.ia-addr = ", binary-to-ascii(16, 16, ":", v6relay(1, option dhcp6.ia-addr))));}
> log(error, concat(" v6relay(1, dhcp6.interface-id) = ", v6relay(1, option dhcp6.interface-id)));
> log(error, concat(" v6relay(1, dhcp6.subscriber-id) = ", v6relay(1, option dhcp6.subscriber-id)));
> log(error, concat(" v6relay(1, dhcp6.relay-id) = ", v6relay(1, option dhcp6.relay-id)));
> # dhcp6.ia-prefix
> log(error, concat(" v6relay(1, dhcp6.ia-prefix) = ", binary-to-ascii(16, 16, ":", suffix(v6relay(1, option dhcp6.ia-prefix), 16)) ) );
> log(error, concat(" dhcp6.ia-na = ", binary-to-ascii(16, 16, ":", suffix(option dhcp6.ia-na, 16)) ) );
> log(error, concat(" dhcp6.ia-ta = ", option dhcp6.ia-ta));
>
> log (error, concat (" v6RELAY1(dhcp6.client-linklayer-addr): ", v6relay(1, (binary-to-ascii(16, 8, ":", option dhcp6.client-linklayer-addr)))));
> log (error, concat (" v6RELAY1(dhcp6.ia-addr): ", v6relay(1, (binary-to-ascii(16, 16, ":", option dhcp6.ia-addr)))));
> log (error, concat (" v6RELAY1(dhcp6.subscriber-id):", v6relay(1, option dhcp6.subscriber-id)));
> log (error, concat (" v6RELAY1(agent.circuit-id):", v6relay(1, option agent.circuit-id)));
> log (error, concat (" v6RELAY1(agent1.remote-id):", v6relay(1, option agent.remote-id)));
> log (error, concat (" dhcp6.remote-id:", option dhcp6.remote-id));
> log (error, concat (" v6RELAY1(dhcp6.ia-na):", substring(suffix(v6relay(1, option dhcp6.ia-na), 24), 0, 16)));
> log (info, concat (" hostname(domain-name):", option domain-name));
>
> log (error, concat ("--> Client-DUID: ",
> binary-to-ascii(16, 8, ":", option dhcp6.client-id),
> " | IP Address: ",
> binary-to-ascii(16, 16, ":", substring(suffix(option dhcp6.ia-na, 24), 0, 16))));
>
> log (error, concat ("--> Client-DUID: ",
> binary-to-ascii(16, 8, ":", option dhcp6.client-id),
> " | Lease IPv6 ",
> binary-to-ascii(16, 16, ":", substring(suffix(option dhcp6.ia-na, 24), 0, 16)),
> " | lease to ",
> v6relay(1, (binary-to-ascii(16, 8, ":", option dhcp6.client-linklayer-addr))),
> " | PD Range: ", binary-to-ascii(16, 16, ":", suffix(option dhcp6.ia-pd, 16)),
> "/",
> binary-to-ascii(10, 8, ":", substring(suffix(option dhcp6.ia-pd, 17), 0, 1)),
> " | MacID: ", binary-to-ascii(16, 8, ":", suffix(option dhcp6.client-id, 6)),
> " | Interface:", v6relay(1, option dhcp6.interface-id))
> );
> }
> on release {
> log(error, concat("RELEASE6 from", agent_circuit-id));
> }
>
>
> On Wed, Jul 03, 2024 at 11:42:35AM -0500, Aaron Gould via juniper-nsp wrote:
> > how are we supposed to deploy ipv6 without the ability to log who has what?
> >
> > -Aaron
> >
> > On 7/3/2024 10:10 AM, Gert Doering via juniper-nsp wrote:
> > > Hi,
> > >
> > > On Wed, Jul 03, 2024 at 10:05:43AM -0500, Chris Adams via juniper-nsp wrote:
> > > > I haven't looked in a bit, but at one point Kea's built-in logging was
> > > > pretty minimal, with "ISP level" logging done as a paid add-on module.
> > > > They've got to pay the bills, but I dislike that model.
> > > pay-for logging might suck, but it's way better than "can you open a
> > > feature request that we'll subsequently ignore" logging...
> > >
> > > gert
> > >
> > > _______________________________________________
> > > juniper-nsp mailing list juniper-nsp at puck.nether.net
> > > https://puck.nether.net/mailman/listinfo/juniper-nsp
> >
> > --
> > -Aaron
> >
> > _______________________________________________
> > juniper-nsp mailing list juniper-nsp at puck.nether.net
> > https://puck.nether.net/mailman/listinfo/juniper-nsp
>
> --
> Jared Mauch | pgp key available via finger from jared at puck.nether.net
> clue++; | http://puck.nether.net/~jared/ My statements are only mine.
> #!/usr/bin/python3
>
> # (c) 2024 Jared Mauch
> #
>
> from isc_dhcp_leases import Lease, IscDhcpLeases
>
> import binascii
>
> leases = IscDhcpLeases('/var/lib/dhcp/dhcpd6.leases')
> #leases.get() # Returns the leases as a list of Lease objects
> #leases.get_current() # Returns only the currently valid dhcp leases as dict
> # The key of the dict is the device mac address and the
> # Value is a Lease object
>
> olts = {}
> olts['F09FC23F7ACC'] = 'olt1'
>
> duids = {}
> duid_info_na = { }
> duid_info_pd = { }
> duid_info_v4 = { }
> duid_info_hostname = { }
> duid_info_cid = { }
> duid_cid_mac = { }
> duid_info_vendor = { }
>
> print("parsing leases6")
> for lease in leases.get():
> # print(lease,vars(lease))
>
> # parse last 6 bytes only
> duidlen = len(lease.duid)
> macloc = duidlen - 6
> # print("duid(len) =", len(lease.duid), macloc)
> duid = ':'.join('{:02x}'.format(x) for x in lease.duid[-6:])
> # print("duid=", duid)
> # duid_info_ip[duid] = lease.ip
> duids[duid] = ':'.join('{:02x}'.format(x) for x in lease.duid)
> # print("duid=", duid)
> cid = lease.options.get('cid', None)
> duid_info_cid[duid] = cid
> if cid is not None:
> duid_cid_mac[cid] = duid_cid_mac.get(cid, 0) + 1
>
> # if duid_info_cid[duid] is not None:
> # print(duid, duid_info_cid[duid])
>
> if lease.type == 'na':
> duid_info_na[duid] = lease.ip
> # print("saving NA lease")
> if lease.type == 'pd':
> duid_info_pd[duid] = lease.ip
> # print("saving PD lease")
> # print(lease.ip, str(lease.type))
>
> # print(lease,vars(lease))
>
>
> print("parsing leases4")
> leases = IscDhcpLeases('/var/lib/dhcp/dhcpd.leases')
> for lease in leases.get():
> if lease.binding_state in ('active'):
> # print(lease,vars(lease))
> # mac_duid = "00:03:00:01:" + lease.ethernet
> mac_duid = lease.ethernet
> duids[mac_duid] = mac_duid
> duid_info_v4[mac_duid] = lease.ip
> cid = lease.options.get('agent.circuit-id', None)
> duid_info_cid[mac_duid] = cid
> if cid is not None:
> duid_cid_mac[cid] = duid_cid_mac.get(cid, 0) + 1
> duid_info_vendor[mac_duid] = lease.sets.get('vendor-class-identifier', '')
> duid_info_hostname[mac_duid] = lease.hostname
> # print('\t', lease.ip, lease.hostname, lease.ethernet, lease.options.get('agent.circuit-id', ''), lease.sets.get('vendor-class-identifier', ''))
>
> print("--- end parsing ---")
> #print(duids)
> for x in sorted(duids.keys()):
> print("hwaddr: %s " % x)
> if x not in duids[x]:
> print("\tHWADDR NOT IN DUID: (%s,%s)" % (x, duids[x]))
> if duid_info_hostname.get(x, None) is not None:
> print("\thostname: %s" % duid_info_hostname.get(x))
> if duid_info_vendor.get(x, None) is not None:
> print("\tvendor: %s" % duid_info_vendor.get(x))
> if duid_info_cid.get(x, None) is not None:
> cid = duid_info_cid.get(x, None)
> cid = cid[1:] # remove first quote
> cid = cid[:-1] # remove last quote?
> vals = cid.split('/')
> olt = vals[0].upper()
> # print(olt, olts.get(olt, None))
> # print(vals)
> print("\tCID:\t(%s)%s\tnum_mac=%d" % (olts.get(olt, None), cid, duid_cid_mac.get(duid_info_cid.get(x))))
> if duid_info_v4.get(x, None) is not None:
> print("\tv4\t%s" % duid_info_v4.get(x))
> if duid_info_na.get(x, None) is not None:
> print("\tNA\t%s" % duid_info_na.get(x))
> if duid_info_pd.get(x, None) is not None:
> print("\tPD\t%s" % duid_info_pd.get(x))
> _______________________________________________
> juniper-nsp mailing list juniper-nsp at puck.nether.net
> https://puck.nether.net/mailman/listinfo/juniper-nsp
--
Jared Mauch | pgp key available via finger from jared at puck.nether.net
clue++; | http://puck.nether.net/~jared/ My statements are only mine.
More information about the juniper-nsp
mailing list