-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suboptimal compilation of window-scaling pflang from jsnellman #215
Comments
Or is this a failure? The --bpf-lua compilation also appears to reject IPv6 as well. Bizarre. |
Yeah, this doesn't really match my mental model of IPv6 support at all, but it's certainly present in libpcap too :-) A more reasonable test case, 'ip6 and tcp and (tcp[tcpflags] != 0)'. This seems to be the offending code in libpcap, so seems like you're bug-compatible :-)
|
@jsnell interesting :)
Passing |
(in case it's not clear, the example from my above comment means that libpcap sees the given expression as always false, so it might not be a pflua bug.) |
...and the reason why 'ip6 and tcp[tcpflags] != 0" doesn't match is because accessing packet data via tcp[] only succeeds if the packet is ipv4. Quoth the "specification": The expression ‘ip[6:2] & 0x1fff = 0’ catches only unfragmented IPv4 datagrams and frag zero of fragmented IPv4 datagrams. This check is implicitly applied to the tcp and udp index operations. For instance, tcp[0] always means the first byte of the TCP header, and never means the first byte of an intervening fragment. |
Edited title to indicate that what I thought was a correctness bug is actually a "feature" of pflang. Leaving the bug open as a task to eventually compile this expression more optimally. |
FWIW current compilation looks like this; haven't taken a look yet to figure out what could be better local lshift = require("bit").lshift
local band = require("bit").band
local cast = require("ffi").cast
return function(P,length)
if length < 54 then return false end
if cast("uint16_t*", P+12)[0] ~= 8 then return false end
if P[23] ~= 6 then return false end
if band(cast("uint16_t*", P+20)[0],65311) ~= 0 then return false end
local v1 = lshift(band(P[14],15),2)
if (v1 + 28) > length then return false end
if band(P[(v1 + 27)],2) == 0 then return false end
local v2 = (v1 + 35)
if v2 > length then return false end
local v3 = P[(v1 + 34)]
if v3 == 3 then return true end
if v3 == 1 then goto L19 end
do
if (v1 + 36) > length then return false end
local v4 = P[v2]
local v5 = (v1 + v4)
local v6 = (v5 + 35)
if v6 > length then return false end
local v7 = P[(v5 + 34)]
if v7 == 3 then return true end
if v7 == 1 then goto L29 end
do
if (v5 + 36) > length then return false end
local v8 = (v4 + P[v6])
local v9 = (v1 + v8)
local v10 = (v9 + 35)
if v10 > length then return false end
local v11 = P[(v9 + 34)]
if v11 == 3 then return true end
if v11 == 1 then goto L39 end
do
if (v9 + 36) > length then return false end
local v12 = (v8 + P[v10])
local v13 = (v1 + v12)
local v14 = (v13 + 35)
if v14 > length then return false end
local v15 = P[(v13 + 34)]
if v15 == 3 then return true end
if v15 == 1 then goto L49 end
do
if (v13 + 36) > length then return false end
local v16 = (v12 + P[v14])
local v17 = (v1 + v16)
local v18 = (v17 + 35)
if v18 > length then return false end
local v19 = P[(v17 + 34)]
if v19 == 3 then return true end
if v19 == 1 then goto L59 end
do
if (v17 + 36) > length then return false end
local v20 = (v1 + (v16 + P[v18]))
if (v20 + 35) > length then return false end
if P[(v20 + 34)] == 3 then return true end
goto L59
end
::L59::
if v19 ~= 1 then goto L49 end
if (v17 + 36) > length then return false end
if P[v18] == 3 then return true end
goto L49
end
::L49::
if v15 ~= 1 then goto L39 end
local v21 = (v13 + 36)
if v21 > length then return false end
local v22 = P[v14]
if v22 == 3 then return true end
if v22 == 1 then goto L77 end
do
if (v13 + 37) > length then return false end
local v23 = (v1 + (v12 + P[v21]))
if (v23 + 36) > length then return false end
if P[(v23 + 35)] == 3 then return true end
goto L77
end
::L77::
if v22 ~= 1 then goto L39 end
if (v13 + 37) > length then return false end
if P[v21] == 3 then return true end
goto L39
end
::L39::
if v11 ~= 1 then goto L29 end
local v24 = (v9 + 36)
if v24 > length then return false end
local v25 = P[v10]
if v25 == 3 then return true end
if v25 == 1 then goto L95 end
do
if (v9 + 37) > length then return false end
local v26 = (v8 + P[v24])
local v27 = (v1 + v26)
local v28 = (v27 + 36)
if v28 > length then return false end
local v29 = P[(v27 + 35)]
if v29 == 3 then return true end
if v29 == 1 then goto L105 end
do
if (v27 + 37) > length then return false end
local v30 = (v1 + (v26 + P[v28]))
if (v30 + 36) > length then return false end
if P[(v30 + 35)] == 3 then return true end
goto L105
end
::L105::
if v29 ~= 1 then goto L95 end
if (v27 + 37) > length then return false end
if P[v28] == 3 then return true end
goto L95
end
::L95::
if v25 ~= 1 then goto L29 end
local v31 = (v9 + 37)
if v31 > length then return false end
local v32 = P[v24]
if v32 == 3 then return true end
if v32 == 1 then goto L123 end
do
if (v9 + 38) > length then return false end
local v33 = (v1 + (v8 + P[v31]))
if (v33 + 37) > length then return false end
if P[(v33 + 36)] == 3 then return true end
goto L123
end
::L123::
if v32 ~= 1 then goto L29 end
if (v9 + 38) > length then return false end
if P[v31] == 3 then return true end
goto L29
end
::L29::
if v7 ~= 1 then goto L19 end
local v34 = (v5 + 36)
if v34 > length then return false end
local v35 = P[v6]
if v35 == 3 then return true end
if v35 == 1 then goto L141 end
do
if (v5 + 37) > length then return false end
local v36 = (v4 + P[v34])
local v37 = (v1 + v36)
local v38 = (v37 + 36)
if v38 > length then return false end
local v39 = P[(v37 + 35)]
if v39 == 3 then return true end
if v39 == 1 then goto L151 end
do
if (v37 + 37) > length then return false end
local v40 = (v36 + P[v38])
local v41 = (v1 + v40)
local v42 = (v41 + 36)
if v42 > length then return false end
local v43 = P[(v41 + 35)]
if v43 == 3 then return true end
if v43 == 1 then goto L161 end
do
if (v41 + 37) > length then return false end
local v44 = (v1 + (v40 + P[v42]))
if (v44 + 36) > length then return false end
if P[(v44 + 35)] == 3 then return true end
goto L161
end
::L161::
if v43 ~= 1 then goto L151 end
if (v41 + 37) > length then return false end
if P[v42] == 3 then return true end
goto L151
end
::L151::
if v39 ~= 1 then goto L141 end
local v45 = (v37 + 37)
if v45 > length then return false end
local v46 = P[v38]
if v46 == 3 then return true end
if v46 == 1 then goto L179 end
do
if (v37 + 38) > length then return false end
local v47 = (v1 + (v36 + P[v45]))
if (v47 + 37) > length then return false end
if P[(v47 + 36)] == 3 then return true end
goto L179
end
::L179::
if v46 ~= 1 then goto L141 end
if (v37 + 38) > length then return false end
if P[v45] == 3 then return true end
goto L141
end
::L141::
if v35 ~= 1 then goto L19 end
local v48 = (v5 + 37)
if v48 > length then return false end
local v49 = P[v34]
if v49 == 3 then return true end
if v49 == 1 then goto L197 end
do
if (v5 + 38) > length then return false end
local v50 = (v4 + P[v48])
local v51 = (v1 + v50)
local v52 = (v51 + 37)
if v52 > length then return false end
local v53 = P[(v51 + 36)]
if v53 == 3 then return true end
if v53 == 1 then goto L207 end
do
if (v51 + 38) > length then return false end
local v54 = (v1 + (v50 + P[v52]))
if (v54 + 37) > length then return false end
if P[(v54 + 36)] == 3 then return true end
goto L207
end
::L207::
if v53 ~= 1 then goto L197 end
if (v51 + 38) > length then return false end
if P[v52] == 3 then return true end
goto L197
end
::L197::
if v49 ~= 1 then goto L19 end
local v55 = (v5 + 38)
if v55 > length then return false end
local v56 = P[v48]
if v56 == 3 then return true end
if v56 == 1 then goto L225 end
do
if (v5 + 39) > length then return false end
local v57 = (v1 + (v4 + P[v55]))
if (v57 + 38) > length then return false end
if P[(v57 + 37)] == 3 then return true end
goto L225
end
::L225::
if v56 ~= 1 then goto L19 end
if (v5 + 39) > length then return false end
if P[v55] == 3 then return true end
goto L19
end
::L19::
if v3 ~= 1 then return false end
local v58 = (v1 + 36)
if v58 > length then return false end
local v59 = P[v2]
if v59 == 3 then return true end
if v59 == 1 then goto L243 end
do
if (v1 + 37) > length then return false end
local v60 = P[v58]
local v61 = (v1 + v60)
local v62 = (v61 + 36)
if v62 > length then return false end
local v63 = P[(v61 + 35)]
if v63 == 3 then return true end
if v63 == 1 then goto L253 end
do
if (v61 + 37) > length then return false end
local v64 = (v60 + P[v62])
local v65 = (v1 + v64)
local v66 = (v65 + 36)
if v66 > length then return false end
local v67 = P[(v65 + 35)]
if v67 == 3 then return true end
if v67 == 1 then goto L263 end
do
if (v65 + 37) > length then return false end
local v68 = (v64 + P[v66])
local v69 = (v1 + v68)
local v70 = (v69 + 36)
if v70 > length then return false end
local v71 = P[(v69 + 35)]
if v71 == 3 then return true end
if v71 == 1 then goto L273 end
do
if (v69 + 37) > length then return false end
local v72 = (v1 + (v68 + P[v70]))
if (v72 + 36) > length then return false end
if P[(v72 + 35)] == 3 then return true end
goto L273
end
::L273::
if v71 ~= 1 then goto L263 end
if (v69 + 37) > length then return false end
if P[v70] == 3 then return true end
goto L263
end
::L263::
if v67 ~= 1 then goto L253 end
local v73 = (v65 + 37)
if v73 > length then return false end
local v74 = P[v66]
if v74 == 3 then return true end
if v74 == 1 then goto L291 end
do
if (v65 + 38) > length then return false end
local v75 = (v1 + (v64 + P[v73]))
if (v75 + 37) > length then return false end
if P[(v75 + 36)] == 3 then return true end
goto L291
end
::L291::
if v74 ~= 1 then goto L253 end
if (v65 + 38) > length then return false end
if P[v73] == 3 then return true end
goto L253
end
::L253::
if v63 ~= 1 then goto L243 end
local v76 = (v61 + 37)
if v76 > length then return false end
local v77 = P[v62]
if v77 == 3 then return true end
if v77 == 1 then goto L309 end
do
if (v61 + 38) > length then return false end
local v78 = (v60 + P[v76])
local v79 = (v1 + v78)
local v80 = (v79 + 37)
if v80 > length then return false end
local v81 = P[(v79 + 36)]
if v81 == 3 then return true end
if v81 == 1 then goto L319 end
do
if (v79 + 38) > length then return false end
local v82 = (v1 + (v78 + P[v80]))
if (v82 + 37) > length then return false end
if P[(v82 + 36)] == 3 then return true end
goto L319
end
::L319::
if v81 ~= 1 then goto L309 end
if (v79 + 38) > length then return false end
if P[v80] == 3 then return true end
goto L309
end
::L309::
if v77 ~= 1 then goto L243 end
local v83 = (v61 + 38)
if v83 > length then return false end
local v84 = P[v76]
if v84 == 3 then return true end
if v84 == 1 then goto L337 end
do
if (v61 + 39) > length then return false end
local v85 = (v1 + (v60 + P[v83]))
if (v85 + 38) > length then return false end
if P[(v85 + 37)] == 3 then return true end
goto L337
end
::L337::
if v84 ~= 1 then goto L243 end
if (v61 + 39) > length then return false end
if P[v83] == 3 then return true end
goto L243
end
::L243::
if v59 ~= 1 then return false end
local v86 = (v1 + 37)
if v86 > length then return false end
local v87 = P[v58]
if v87 == 3 then return true end
if v87 == 1 then goto L355 end
do
if (v1 + 38) > length then return false end
local v88 = P[v86]
local v89 = (v1 + v88)
local v90 = (v89 + 37)
if v90 > length then return false end
local v91 = P[(v89 + 36)]
if v91 == 3 then return true end
if v91 == 1 then goto L365 end
do
if (v89 + 38) > length then return false end
local v92 = (v88 + P[v90])
local v93 = (v1 + v92)
local v94 = (v93 + 37)
if v94 > length then return false end
local v95 = P[(v93 + 36)]
if v95 == 3 then return true end
if v95 == 1 then goto L375 end
do
if (v93 + 38) > length then return false end
local v96 = (v1 + (v92 + P[v94]))
if (v96 + 37) > length then return false end
if P[(v96 + 36)] == 3 then return true end
goto L375
end
::L375::
if v95 ~= 1 then goto L365 end
if (v93 + 38) > length then return false end
if P[v94] == 3 then return true end
goto L365
end
::L365::
if v91 ~= 1 then goto L355 end
local v97 = (v89 + 38)
if v97 > length then return false end
local v98 = P[v90]
if v98 == 3 then return true end
if v98 == 1 then goto L393 end
do
if (v89 + 39) > length then return false end
local v99 = (v1 + (v88 + P[v97]))
if (v99 + 38) > length then return false end
if P[(v99 + 37)] == 3 then return true end
goto L393
end
::L393::
if v98 ~= 1 then goto L355 end
if (v89 + 39) > length then return false end
if P[v97] == 3 then return true end
goto L355
end
::L355::
if v87 ~= 1 then return false end
local v100 = (v1 + 38)
if v100 > length then return false end
local v101 = P[v86]
if v101 == 3 then return true end
if v101 == 1 then goto L411 end
do
if (v1 + 39) > length then return false end
local v102 = P[v100]
local v103 = (v1 + v102)
local v104 = (v103 + 38)
if v104 > length then return false end
local v105 = P[(v103 + 37)]
if v105 == 3 then return true end
if v105 == 1 then goto L421 end
do
if (v103 + 39) > length then return false end
local v106 = (v1 + (v102 + P[v104]))
if (v106 + 38) > length then return false end
if P[(v106 + 37)] == 3 then return true end
goto L421
end
::L421::
if v105 ~= 1 then goto L411 end
if (v103 + 39) > length then return false end
if P[v104] == 3 then return true end
goto L411
end
::L411::
if v101 ~= 1 then return false end
local v107 = (v1 + 39)
if v107 > length then return false end
local v108 = P[v100]
if v108 == 3 then return true end
if v108 == 1 then goto L439 end
do
if (v1 + 40) > length then return false end
local v109 = (v1 + P[v107])
if (v109 + 39) > length then return false end
if P[(v109 + 38)] == 3 then return true end
goto L439
end
::L439::
if v108 ~= 1 then return false end
if (v1 + 40) > length then return false end
return P[v107] == 3
end |
This test exercises spilling for the dynasm backend pretty well and exposed a bug
Fix spilling & add a big test from issue #215
The following pflang is from Juho Snellman's blog post, and looks for the window-scaling option among the first 6 TCP options. I think it miscompiles though, because it looks like the whole ip6 block folds for some reason.
The text was updated successfully, but these errors were encountered: