From 0451b2aa879985ad303f2ecd4f026c5eed3a6164 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 19 May 2026 07:57:47 -0700 Subject: [PATCH] Add Global Internet Table dashboard (roadmap E3) Explores the real DFZ table received from the AS57355 route server via the GoBGP feed (the '$feed' / GoBGP BMP peer): IPv4/IPv6 prefix counts, distinct origin ASes, prefix-length distribution, top origin ASes by prefix count, and an overlap-based prefix lookup. Serves as the comparison baseline for the Router Diff dashboard. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../obmp/History-1002/global_table.json | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 obmp-grafana/dashboards/obmp/History-1002/global_table.json diff --git a/obmp-grafana/dashboards/obmp/History-1002/global_table.json b/obmp-grafana/dashboards/obmp/History-1002/global_table.json new file mode 100644 index 0000000..49d70ab --- /dev/null +++ b/obmp-grafana/dashboards/obmp/History-1002/global_table.json @@ -0,0 +1,117 @@ +{ + "annotations": {"list": [{"builtIn": 1,"datasource": {"type": "datasource","uid": "grafana"},"enable": true,"hide": true,"iconColor": "rgba(0, 211, 255, 1)","name": "Annotations & Alerts","type": "dashboard"}]}, + "description": "Explores the real Internet routing table pulled by the GoBGP feed (roadmap E3) — the eBGP-multihop session to the AS57355 route server, landed in ip_rib as the '$feed' peer. Use it as the comparison baseline for the Router Diff dashboard.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [{"asDropdown": true,"icon": "external link","includeVars": true,"keepTime": true,"tags": ["obmp-nav"],"title": "OBMP Dashboards","type": "dashboards"}], + "liveNow": false, + "panels": [ + { + "datasource": {"type": "datasource","uid": "grafana"}, + "gridPos": {"h": 4,"w": 24,"x": 0,"y": 0}, + "id": 10, + "options": {"code": {"language": "plaintext","showLineNumbers": false,"showMiniMap": false},"content": "## Global Internet Table\n\nThe real DFZ routing table received from the **AS57355** lab route server via the GoBGP feed, monitored over BMP and stored in `ip_rib` as the **$feed** peer. AS57355 is prepended to every AS path (it is the route server). This dashboard is the comparison baseline for **Router Diff** — select `$feed` there to diff a lab router against the real Internet. Counts grow as the table converges (~1M IPv4 + ~200k IPv6 once fully loaded).","mode": "markdown"}, + "pluginVersion": "9.1.7", + "type": "text" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Distinct IPv4 prefixes in the global feed.", + "fieldConfig": {"defaults": {"color": {"mode": "thresholds"},"thresholds": {"mode": "absolute","steps": [{"color": "blue","value": null}]},"unit": "short"},"overrides": []}, + "gridPos": {"h": 4,"w": 8,"x": 0,"y": 4}, + "id": 1, + "options": {"colorMode": "value","graphMode": "none","justifyMode": "auto","orientation": "auto","reduceOptions": {"calcs": ["lastNotNull"],"fields": "","values": false},"textMode": "auto"}, + "pluginVersion": "9.1.7", + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT count(*) AS \"IPv4 Prefixes\" FROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id WHERE rt.name = '$feed' AND r.iswithdrawn = false AND r.isipv4","refId": "A"}], + "title": "IPv4 Prefixes","type": "stat" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Distinct IPv6 prefixes in the global feed. Requires the IPv6 session — see gobgp/README.md.", + "fieldConfig": {"defaults": {"color": {"mode": "thresholds"},"thresholds": {"mode": "absolute","steps": [{"color": "purple","value": null}]},"unit": "short"},"overrides": []}, + "gridPos": {"h": 4,"w": 8,"x": 8,"y": 4}, + "id": 2, + "options": {"colorMode": "value","graphMode": "none","justifyMode": "auto","orientation": "auto","reduceOptions": {"calcs": ["lastNotNull"],"fields": "","values": false},"textMode": "auto"}, + "pluginVersion": "9.1.7", + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT count(*) AS \"IPv6 Prefixes\" FROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id WHERE rt.name = '$feed' AND r.iswithdrawn = false AND NOT r.isipv4","refId": "A"}], + "title": "IPv6 Prefixes","type": "stat" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Distinct origin ASes across the global feed.", + "fieldConfig": {"defaults": {"color": {"mode": "thresholds"},"thresholds": {"mode": "absolute","steps": [{"color": "green","value": null}]},"unit": "short"},"overrides": []}, + "gridPos": {"h": 4,"w": 8,"x": 16,"y": 4}, + "id": 3, + "options": {"colorMode": "value","graphMode": "none","justifyMode": "auto","orientation": "auto","reduceOptions": {"calcs": ["lastNotNull"],"fields": "","values": false},"textMode": "auto"}, + "pluginVersion": "9.1.7", + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT count(DISTINCT r.origin_as) AS \"Origin ASes\" FROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id WHERE rt.name = '$feed' AND r.iswithdrawn = false AND r.origin_as IS NOT NULL","refId": "A"}], + "title": "Origin ASes","type": "stat" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Prefix-length distribution. A real table peaks hard at /24 (IPv4) and /48 (IPv6).", + "fieldConfig": {"defaults": {"color": {"mode": "continuous-BlPu"},"custom": {"lineWidth": 1,"fillOpacity": 80,"axisPlacement": "auto"}},"overrides": []}, + "gridPos": {"h": 9,"w": 24,"x": 0,"y": 8}, + "id": 4, + "options": {"orientation": "vertical","showValue": "auto","xField": "Length","legend": {"showLegend": false},"tooltip": {"mode": "single"}}, + "pluginVersion": "9.1.7", + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT (CASE WHEN r.isipv4 THEN 'v4 /' ELSE 'v6 /' END || r.prefix_len) AS \"Length\",\n count(*) AS \"Prefixes\"\nFROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id\nWHERE rt.name = '$feed' AND r.iswithdrawn = false\nGROUP BY r.isipv4, r.prefix_len\nORDER BY r.isipv4 DESC, r.prefix_len","refId": "A"}], + "title": "Prefix-Length Distribution","type": "barchart" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "ASes originating the most prefixes in the global table, with whois names.", + "fieldConfig": {"defaults": {"custom": {"align": "auto","displayMode": "auto"}},"overrides": [{"matcher": {"id": "byName","options": "Prefixes"},"properties": [{"id": "custom.displayMode","value": "gradient-gauge"},{"id": "color","value": {"mode": "continuous-BlPu"}}]}]}, + "gridPos": {"h": 9,"w": 12,"x": 0,"y": 17}, + "id": 5, + "options": {"showHeader": true,"sortBy": [{"desc": true,"displayName": "Prefixes"}]}, + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT r.origin_as AS \"Origin AS\",\n COALESCE(NULLIF(ia.as_name,''),'AS' || r.origin_as) AS \"Name\",\n COALESCE(NULLIF(ia.country,''),'?') AS \"Country\",\n count(*) AS \"Prefixes\"\nFROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id\nLEFT JOIN info_asn ia ON ia.asn = r.origin_as\nWHERE rt.name = '$feed' AND r.iswithdrawn = false AND r.origin_as IS NOT NULL\nGROUP BY r.origin_as, ia.as_name, ia.country\nORDER BY count(*) DESC LIMIT 50","refId": "A"}], + "title": "Top Origin ASes by Prefix Count","type": "table" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Prefix-length count as a sortable table (companion to the bar chart).", + "fieldConfig": {"defaults": {"custom": {"align": "auto","displayMode": "auto"}},"overrides": [{"matcher": {"id": "byName","options": "Prefixes"},"properties": [{"id": "custom.displayMode","value": "gradient-gauge"},{"id": "color","value": {"mode": "continuous-GrYlRd"}}]}]}, + "gridPos": {"h": 9,"w": 12,"x": 12,"y": 17}, + "id": 6, + "options": {"showHeader": true,"sortBy": [{"desc": true,"displayName": "Prefixes"}]}, + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT CASE WHEN r.isipv4 THEN 'IPv4' ELSE 'IPv6' END AS \"AFI\",\n r.prefix_len AS \"Prefix Length\",\n count(*) AS \"Prefixes\"\nFROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id\nWHERE rt.name = '$feed' AND r.iswithdrawn = false\nGROUP BY r.isipv4, r.prefix_len\nORDER BY count(*) DESC","refId": "A"}], + "title": "Prefix Lengths","type": "table" + }, + { + "collapsed": false, + "gridPos": {"h": 1,"w": 24,"x": 0,"y": 26}, + "id": 11, + "panels": [], + "title": "Prefix Lookup","type": "row" + }, + { + "datasource": {"type": "postgres","uid": "obmp_postgres"}, + "description": "Enter a prefix or CIDR block in the 'Search prefix' box (e.g. 8.8.8.0/24 or 1.0.0.0/8). Shows every route in the global table that overlaps it — the exact prefix plus more- and less-specifics.", + "fieldConfig": {"defaults": {"custom": {"align": "auto","displayMode": "auto"}},"overrides": []}, + "gridPos": {"h": 11,"w": 24,"x": 0,"y": 27}, + "id": 7, + "options": {"showHeader": true,"sortBy": [{"desc": false,"displayName": "Prefix"}]}, + "targets": [{"datasource": {"type": "postgres","uid": "obmp_postgres"},"format": "table","rawSql": "SELECT host(r.prefix) || '/' || r.prefix_len AS \"Prefix\",\n r.origin_as AS \"Origin AS\",\n COALESCE(NULLIF(ia.as_name,''),'AS' || r.origin_as) AS \"Origin Name\",\n host(ba.next_hop) AS \"Next Hop\",\n ba.as_path::text AS \"AS Path\",\n array_length(ba.as_path,1) AS \"Path Len\",\n r.timestamp AS \"Last Update\"\nFROM ip_rib r JOIN bgp_peers p ON p.hash_id = r.peer_hash_id JOIN routers rt ON rt.hash_id = p.router_hash_id\nJOIN base_attrs ba ON ba.hash_id = r.base_attr_hash_id\nLEFT JOIN info_asn ia ON ia.asn = r.origin_as\nWHERE rt.name = '$feed' AND r.iswithdrawn = false\n AND r.prefix && NULLIF('$search_prefix','')::inet\nORDER BY r.prefix, r.prefix_len LIMIT 500","refId": "A"}], + "title": "Routes Overlapping $search_prefix","type": "table" + } + ], + "schemaVersion": 36, + "style": "dark", + "tags": ["obmp", "obmp-nav", "bgp", "global"], + "templating": { + "list": [ + {"name": "feed","type": "custom","label": "Feed router","description": "The BMP router name of the global-table feed (the GoBGP container).","query": "GoBGP","current": {"text": "GoBGP","value": "GoBGP"},"options": [{"text": "GoBGP","value": "GoBGP","selected": true}],"hide": 0}, + {"name": "search_prefix","type": "textbox","label": "Search prefix","description": "A prefix or CIDR block to look up in the global table (e.g. 8.8.8.0/24). Blank = no lookup.","query": "","current": {"text": "","value": ""},"options": [{"text": "","value": "","selected": true}],"hide": 0} + ] + }, + "time": {"from": "now-6h","to": "now"}, + "timepicker": {}, + "timezone": "", + "title": "Global Internet Table", + "uid": "global-table", + "version": 1, + "weekStart": "" +}