Perhaps it will help you:
tcpdump 'ip6[6]==17 or udp or (ip6[6]==6 and ip6[53]&8!=0) or tcp[13]&8!=0' -X -r some.pcap
In tcpdump you can't retrieve ipv6 packets the way you are trying, because it does not support (at least up to 4.9.2 version) BPF filters under ipv6.
So,
ip6[6]==17
means udp over ipv6 (the 6th byte is the ipv6-header protocol field), ip6[6]==6
means tcp over ipv6 respectively;
ip6[53]&8!=0
means tcp-push over ipv6 (40 bytes of ipv6-header and 13th byte of tcp-header, which is tcp-flags);
tcp[13]&8!=0
is the same as your tcp[tcpflags] & tcp-push != 0
.
More info: ipv6 tcpip pocketguide and here.
Keep in mind (!): Using ip6[6]
to identify the protocol fails if any extension headers are present (as pointed by kasperd). More about ipv6 extension headers here. Hence such way tcp-packets over ipv6 with extension headers will not be captured.
Also, you can write your own simple filter for specific (e.g. to get the last character of payload) purposes like:
perl -le 'print map { /(?:Flags \[P\.\]|UDP).*(\S)$/s } split /\d{2}:\d{2}:\d{2}\.\d{6}/, `tcpdump -X -r some.pcap 2>/dev/null`'
tcpdump
.