mbox series

[net-next,v3,00/13] flow_dissector: Dissect UDP encapsulation protocols

Message ID 20240821212212.1795357-1-tom@herbertland.com (mailing list archive)
Headers show
Series flow_dissector: Dissect UDP encapsulation protocols | expand

Message

Tom Herbert Aug. 21, 2024, 9:21 p.m. UTC
Add support in flow_dissector for dissecting into UDP
encapsulations like VXLAN. __skb_flow_dissect_udp is called for
IPPROTO_UDP. The flag FLOW_DISSECTOR_F_PARSE_UDP_ENCAPS enables parsing
of UDP encapsulations. If the flag is set when parsing a UDP packet then
a socket lookup is performed. The offset of the base network header,
either an IPv4 or IPv6 header, is tracked and passed to
__skb_flow_dissect_udp so that it can perform the socket lookup.
If a socket is found and it's for a UDP encapsulation (encap_type is
set in the UDP socket) then a switch is performed on the encap_type
value (cases are UDP_ENCAP_* values)

Changes in the patch set:

- Unconstantify struct net argument in flowdis functions so we can call
  UDP socket lookup functions
- Dissect ETH_P_TEB in main flow dissector loop, move ETH_P_TEB check
  out of __skb_flow_dissect_gre and process it in main loop
- Add UDP_ENCAP constants for tipc, fou, gue, sctp, rxe, pfcp,
  wireguard, bareudp, vxlan, vxlan_gpe, geneve, and amt
- For the various UDP encapsulation protocols, Instead of just setting
  UDP tunnel encap type to 1, set it to the corresponding UDP_ENCAP
  constant. This allows identify the encapsulation protocol for a
  UDP socket by the encap_type
- Add function __skb_flow_dissect_udp in flow_dissector and call it for
  UDP packets. If a UDP encapsulation is present then the function
  returns either FLOW_DISSECT_RET_PROTO_AGAIN or
  FLOW_DISSECT_RET_IPPROTO_AGAIN
- Add flag FLOW_DISSECTOR_F_PARSE_UDP_ENCAPS that indicates UDP
  encapsulations should be dissected
- Add __skb_flow_dissect_vxlan which is called when encap_type is
  UDP_ENCAP_VXLAN or UDP_ENCAP_VXLAN_GPE. Dissect VXLAN and return
  a next protocol and offset
- Add __skb_flow_dissect_fou which is called when encap_type is
  UDP_ENCAP_FOU. Dissect FOU and return a next protocol and offset
- Add support for ESP, L2TP, and SCTP in UDP in __skb_flow_dissect_udp.
  All we need to do is return FLOW_DISSECT_RET_IPPROTO_AGAIN and the
  corresponding IP protocol number
- Add __skb_flow_dissect_geneve which is called when encap_type is
  UDP_ENCAP_GENEVE. Dissect geneve and return a next protocol and offset
- Add __skb_flow_dissect_gue which is called when encap_type is
  UDP_ENCAP_GUE. Dissect gue and return a next protocol and offset
- Add __skb_flow_dissect_gtp which is called when encap_type is
  UDP_ENCAP_GTP. Dissect gtp and return a next protocol and offset

Tested: Verified fou, gue, vxlan, and geneve are properly dissected for
IPv4 and IPv6 cases. This includes testing ETH_P_TEB case

v2:
- Add #if IS_ENABLED(CONFIG_IPV6) around IPv6 cases when dissecting UDP.
  Also, c all ipv6_bpf_stub->udp6_lib_lookup instead of udp6_lib_lookup
  directly since udp6_lib_lookup in the IPv6 module
- Drop patch to unconstantify struct net argument in flowdis functions,
  edumazet added const to ne argument in UDP socket lookup functions
- As support in flowdis ipproto switch for no-next-hdr. Just exit
  flowdis on good result when this is seen
- Merge patches that move TEB processing out of GRE and moved into
  main protocol switch
- Rename bpoff in UDP flow dissector functions to be base_nhoff for
  clarity
- Parse GTPv1 extension headers (part of this is moving
  gtp_parse_exthdrs to a header file
- Exit flowdis on good result if NPDU or SEQ GTPv1 flags are set

v3:
- Add udp6_lib_lookup to ipv6_stubs
- Call ipv6_stubs->udp6_lib_lookup instead of ipv6_bpf_stubs variant
- Use _HF_ variants of VLXAN flags (those in network byte order)
- Use encap type from socket to determine if a packet is VXLAN-GPE instead
  of getting this from flags
- Protect both IPv4 and IPv6 cases with #ifdef CONFIG_INET
- Added a comment why UDP_ENCAP constants are in uapi
- Added a comment in ETH_P_TEB case why NET_IP_ALIGN is needed
- Add a check in __skb_flow_dissect_udp that the netns for the
  skb device is the same as the caller's netns, and also only
  dissect UDP is we haven't yet encountered any encapsulation.
  The goal is to ensure that the socket lookup is being done in the
  right netns. Encapsulations may push packets into different name
  spaces, so this scheme is restricting UDP dieesction to cases where
  there are not name spaces or at least the original name space.
  This should capture the majority of use cases for UDP encaps,
  if we do encounter a UDP encapsulation within a different namespace
  then the only effect is we don't attempt UDP dissection

Tom Herbert (13):
  ipv6: Add udp6_lib_lookup to IPv6 stubs
  flow_dissector: Parse ETH_P_TEB and move out of GRE
  udp_encaps: Add new UDP_ENCAP constants
  udp_encaps: Set proper UDP_ENCAP types in tunnel setup
  flow_dissector: UDP encap infrastructure
  flow_dissector: Parse vxlan in UDP
  flow_dissector: Parse foo-over-udp (FOU)
  flow_dissector: Parse ESP, L2TP, and SCTP in UDP
  flow_dissector: Parse Geneve in UDP
  flow_dissector: Parse GUE in UDP
  gtp: Move gtp_parse_exthdrs into net/gtp.h
  flow_dissector: Parse gtp in UDP
  flow_dissector: Add case in ipproto switch for NEXTHDR_NONE

 drivers/infiniband/sw/rxe/rxe_net.c |   2 +-
 drivers/net/amt.c                   |   2 +-
 drivers/net/bareudp.c               |   2 +-
 drivers/net/geneve.c                |   2 +-
 drivers/net/gtp.c                   |  37 ---
 drivers/net/pfcp.c                  |   2 +-
 drivers/net/vxlan/vxlan_core.c      |   3 +-
 drivers/net/wireguard/socket.c      |   2 +-
 include/net/flow_dissector.h        |   1 +
 include/net/fou.h                   |  16 +
 include/net/gtp.h                   |  38 +++
 include/net/ipv6_stubs.h            |   5 +
 include/uapi/linux/udp.h            |  19 +-
 net/core/flow_dissector.c           | 468 ++++++++++++++++++++++++++--
 net/ipv4/fou_core.c                 |  19 +-
 net/ipv6/af_inet6.c                 |   1 +
 net/sctp/protocol.c                 |   2 +-
 net/tipc/udp_media.c                |   2 +-
 18 files changed, 533 insertions(+), 90 deletions(-)