I believe we're off by one in generating the ttl_exceeded message (it's shown as 1 below, and means that traceroute displays an intermediate hop for our address when we're actually the target).
We're also not generating an ICMP "port unreachable" message in response to the UDP packet to an unused port, which is the usual traceroute signal of having reached the ultimate node.
Both should be simple to fix and are I believe mostly cosmetic.
Packet 1
06:12:21:219031: dpdk-input
af_packet0 rx queue 0
buffer 0x10e6b: current data 0, length 74, free-list 0, totlen-nifb 0, trace 0x0
PKT MBUF: port 0, nb_segs 1, pkt_len 74
buf_len 2176, data_len 74, ol_flags 0x0,
packet_type 0x0
IP4: 00:08:a2:09:5b:81 -> 02:fe:d5:24:68:49
UDP: 192.168.1.2 -> 192.168.2.2
tos 0x00, ttl 1, length 60, checksum 0xb722
fragment id 0x7e3a
UDP: 39891 -> 33437
length 40, checksum 0x67d3
06:12:21:219037: ethernet-input
IP4: 00:08:a2:09:5b:81 -> 02:fe:d5:24:68:49
06:12:21:219041: ip4-input
UDP: 192.168.1.2 -> 192.168.2.2
tos 0x00, ttl 1, length 60, checksum 0xb722
fragment id 0x7e3a
UDP: 39891 -> 33437
length 40, checksum 0x67d3
06:12:21:219043: ip4-icmp-error
UDP: 192.168.1.2 -> 192.168.2.2
tos 0x00, ttl 1, length 60, checksum 0xb722
fragment id 0x7e3a
UDP: 39891 -> 33437
length 40, checksum 0x67d3
06:12:21:219057: ip4-rewrite-transit
fib 0 adj-idx 6 : af_packet0
IP4: 02:fe:d5:24:68:49 -> 00:08:a2:09:5b:81 next_adj_with_signature 5 flow hash: 0x00000000
IP4: 02:fe:d5:24:68:49 -> 00:08:a2:09:5b:81
ICMP: 192.168.2.2 -> 192.168.1.2
tos 0x00, ttl 254, length 88, checksum 0x3850
fragment id 0x0000
ICMP time_exceeded ttl_exceeded_in_transit checksum 0x798e
06:12:21:219060: af_packet0-output
af_packet0
IP4: 02:fe:d5:24:68:49 -> 00:08:a2:09:5b:81
ICMP: 192.168.2.2 -> 192.168.1.2
tos 0x00, ttl 254, length 88, checksum 0x3850
fragment id 0x0000
ICMP time_exceeded ttl_exceeded_in_transit checksum 0x798e
06:12:21:219062: af_packet0-tx
af_packet0 tx queue 0
buffer 0x10e6b: current data -28, length 102, free-list 0, totlen-nifb 0, trace 0x0
IP4: 02:fe:d5:24:68:49 -> 00:08:a2:09:5b:81
ICMP: 192.168.2.2 -> 192.168.1.2
tos 0x00, ttl 254, length 88, checksum 0x3850
fragment id 0x0000
ICMP time_exceeded ttl_exceeded_in_transit checksum 0x798e
...
Packet 4
06:12:21:219131: dpdk-input
af_packet0 rx queue 0
buffer 0x10e6b: current data 0, length 74, free-list 0, totlen-nifb 0, trace 0x3
PKT MBUF: port 0, nb_segs 1, pkt_len 74
buf_len 2176, data_len 74, ol_flags 0x0,
packet_type 0x0
IP4: 00:08:a2:09:5b:81 -> 02:fe:d5:24:68:49
UDP: 192.168.1.2 -> 192.168.2.2
tos 0x00, ttl 2, length 60, checksum 0xb61f
fragment id 0x7e3d
UDP: 34299 -> 33440
length 40, checksum 0x7da8
06:12:21:219147: ethernet-input
IP4: 00:08:a2:09:5b:81 -> 02:fe:d5:24:68:49
06:12:21:219153: ip4-input
UDP: 192.168.1.2 -> 192.168.2.2
tos 0x00, ttl 2, length 60, checksum 0xb61f
fragment id 0x7e3d
UDP: 34299 -> 33440
length 40, checksum 0x7da8
06:12:21:219158: ip4-local
fib 0 adj-idx 4 : local 192.168.2.2/24 flow hash: 0x00000000
06:12:21:219162: ip4-udp-lookup
UDP: src-port 34299 dst-port 33440
06:12:21:219170: error-punt
ip4-udp-lookup: no listener for dst port