Skip to content

Commit

Permalink
apps.ipfix: support IPv6 prefix to AS mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
eugeneia committed Apr 26, 2022
1 parent 657c884 commit c154ab1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 15 deletions.
35 changes: 23 additions & 12 deletions src/apps/ipfix/maps.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,27 @@ local function make_vlan_to_ifindex_map(name)
return table
end

-- Map IPv4 address to AS number
-- Map IP address to AS number
--
-- Used to set bgpSourceAsNumber, bgpDestinationAsNumber from the IPv4
-- Used to set bgpSourceAsNumber, bgpDestinationAsNumber from the IP
-- source and destination address, respectively. The file contains a
-- list of prefixes and their proper source AS number based on
-- authoritative data from the RIRs. This parser supports the format
-- used by the Geo2Lite database provided by MaxMind:
-- http://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN-CSV.zip
local function make_pfx_to_as_map(name)
local table = { pt = poptrie.new{direct_pointing=true},
asn = {},
search_bytes = function (self, a)
return self.asn[self.pt:lookup32(a)]
end }
local function make_pfx_to_as_map(name, proto)
local table = { pt = poptrie.new{direct_pointing=true}, asn = {} }
if proto == ipv4 then
function table:search_bytes (a)
return self.asn[self.pt:lookup32(a)]
end
elseif proto == ipv6 then
function table:search_bytes (a)
return self.asn[self.pt:lookup128(a)]
end
else
error("Proto must be ipv4 or ipv6")
end
for line in assert(io.lines(name)) do
if not line:match("^network") then
local cidr, asn = line:match("([^,]*),(%d+),")
Expand All @@ -87,7 +94,7 @@ local function make_pfx_to_as_map(name)
local id = #asn+1
assert(id < 2^16, "Prefix-to-AS map: poptrie overflow")
table.asn[id] = asn
local pfx, len = ipv4:pton_cidr(cidr)
local pfx, len = proto:pton_cidr(cidr)
table:add(pfx, len, id)
end
end
Expand All @@ -104,9 +111,13 @@ local map_info = {
create_fn = make_vlan_to_ifindex_map,
logger_module = 'VLAN to ifIndex mapper'
},
pfx_to_as = {
create_fn = make_pfx_to_as_map,
logger_module = 'Prefix to AS mapper'
pfx4_to_as = {
create_fn = function (name) return make_pfx_to_as_map(name, ipv4) end,
logger_module = 'IPv4 prefix to AS mapper'
},
pfx6_to_as = {
create_fn = function (name) return make_pfx_to_as_map(name, ipv6) end,
logger_module = 'IPv6 prefix to AS mapper'
}
}

Expand Down
23 changes: 20 additions & 3 deletions src/apps/ipfix/template.lua
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ local function v4_extended_extract (self, pkt, timestamp, entry)
local md = metadata_get(pkt)
extended_extract(self, pkt, md, timestamp, entry, extract_v4_addr)

local pfx_to_as = self.maps.pfx_to_as
local pfx_to_as = self.maps.pfx4_to_as
local asn = pfx_to_as.map:search_bytes(entry.key.sourceIPv4Address)
if asn then
entry.value.bgpSourceAsNumber = asn
Expand Down Expand Up @@ -600,6 +600,23 @@ end
local function v6_extended_extract (self, pkt, timestamp, entry)
local md = metadata_get(pkt)
extended_extract(self, pkt, md, timestamp, entry, extract_v6_addr)

local pfx_to_as = self.maps.pfx6_to_as
local asn = pfx_to_as.map:search_bytes(entry.key.sourceIPv6Address)
if asn then
entry.value.bgpSourceAsNumber = asn
elseif can_log(pfx_to_as.logger) then
pfx_to_as.logger:log("missing AS for source "
..ipv6:ntop(entry.key.sourceIPv6Address))
end
local asn = pfx_to_as.map:search_bytes(entry.key.destinationIPv6Address)
if asn then
entry.value.bgpDestinationAsNumber = asn
elseif can_log(pfx_to_as.logger) then
pfx_to_as.logger:log("missing AS for destination "
..ipv6:ntop(entry.key.destinationIPv6Address))
end

entry.value.ipClassOfService = get_ipv6_tc(md.l3)
if md.proto == IP_PROTO_ICMP6 and md.frag_offset == 0 then
entry.value.icmpTypeCodeIPv6 = get_icmp_typecode(md.l4)
Expand Down Expand Up @@ -729,7 +746,7 @@ templates = {
"icmpTypeCodeIPv4",
"ingressInterface",
"egressInterface" },
require_maps = { 'mac_to_as', 'vlan_to_ifindex', 'pfx_to_as' },
require_maps = { 'mac_to_as', 'vlan_to_ifindex', 'pfx4_to_as' },
extract = v4_extended_extract,
accumulate = v4_extended_accumulate
},
Expand Down Expand Up @@ -848,7 +865,7 @@ templates = {
"icmpTypeCodeIPv6",
"ingressInterface",
"egressInterface" },
require_maps = { 'mac_to_as', 'vlan_to_ifindex', 'pfx_to_as' },
require_maps = { 'mac_to_as', 'vlan_to_ifindex', 'pfx6_to_as' },
extract = v6_extended_extract,
accumulate = v6_extended_accumulate,
},
Expand Down

0 comments on commit c154ab1

Please sign in to comment.