flow_dissector: Add L2TPv3 dissectors
authorWojciech Drewek <wojciech.drewek@intel.com>
Thu, 8 Sep 2022 17:16:41 +0000 (10:16 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 20 Sep 2022 07:13:38 +0000 (09:13 +0200)
Allow to dissect L2TPv3 specific field which is:
- session ID (32 bits)

L2TPv3 might be transported over IP or over UDP,
this implementation is only about L2TPv3 over IP.
IP protocol carries L2TPv3 when ip_proto is
IPPROTO_L2TP (115).

Acked-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/flow_dissector.h
net/core/flow_dissector.c

index 6c74812d64b2629c3ade83ce520408a78d7e2510..5ccf52ef8809988e39395e9801911764007354ed 100644 (file)
@@ -289,6 +289,14 @@ struct flow_dissector_key_pppoe {
        __be16 type;
 };
 
+/**
+ * struct flow_dissector_key_l2tpv3:
+ * @session_id: identifier for a l2tp session
+ */
+struct flow_dissector_key_l2tpv3 {
+       __be32 session_id;
+};
+
 enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
        FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -320,6 +328,7 @@ enum flow_dissector_key_id {
        FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
        FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
        FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
+       FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
 
        FLOW_DISSECTOR_KEY_MAX,
 };
index 990429c69ccd41400eba69008f00f35cfc336559..2a1f513a2dc861d2d1d8f5bac816ff8e6bfa7692 100644 (file)
@@ -204,6 +204,30 @@ static void __skb_flow_dissect_icmp(const struct sk_buff *skb,
        skb_flow_get_icmp_tci(skb, key_icmp, data, thoff, hlen);
 }
 
+static void __skb_flow_dissect_l2tpv3(const struct sk_buff *skb,
+                                     struct flow_dissector *flow_dissector,
+                                     void *target_container, const void *data,
+                                     int nhoff, int hlen)
+{
+       struct flow_dissector_key_l2tpv3 *key_l2tpv3;
+       struct {
+               __be32 session_id;
+       } *hdr, _hdr;
+
+       if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_L2TPV3))
+               return;
+
+       hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
+       if (!hdr)
+               return;
+
+       key_l2tpv3 = skb_flow_dissector_target(flow_dissector,
+                                              FLOW_DISSECTOR_KEY_L2TPV3,
+                                              target_container);
+
+       key_l2tpv3->session_id = hdr->session_id;
+}
+
 void skb_flow_dissect_meta(const struct sk_buff *skb,
                           struct flow_dissector *flow_dissector,
                           void *target_container)
@@ -1501,6 +1525,10 @@ ip_proto_again:
                __skb_flow_dissect_icmp(skb, flow_dissector, target_container,
                                        data, nhoff, hlen);
                break;
+       case IPPROTO_L2TP:
+               __skb_flow_dissect_l2tpv3(skb, flow_dissector, target_container,
+                                         data, nhoff, hlen);
+               break;
 
        default:
                break;