#include <linux/tracepoint.h>
  #include <net/ipv6.h>
  
 -#define tcp_state_name(state) { state, #state }
 -#define show_tcp_state_name(val)                      \
 -      __print_symbolic(val,                           \
 -              tcp_state_name(TCP_ESTABLISHED),        \
 -              tcp_state_name(TCP_SYN_SENT),           \
 -              tcp_state_name(TCP_SYN_RECV),           \
 -              tcp_state_name(TCP_FIN_WAIT1),          \
 -              tcp_state_name(TCP_FIN_WAIT2),          \
 -              tcp_state_name(TCP_TIME_WAIT),          \
 -              tcp_state_name(TCP_CLOSE),              \
 -              tcp_state_name(TCP_CLOSE_WAIT),         \
 -              tcp_state_name(TCP_LAST_ACK),           \
 -              tcp_state_name(TCP_LISTEN),             \
 -              tcp_state_name(TCP_CLOSING),            \
 -              tcp_state_name(TCP_NEW_SYN_RECV))
 -
+ #define TP_STORE_V4MAPPED(__entry, saddr, daddr)              \
+       do {                                                    \
+               struct in6_addr *pin6;                          \
+                                                               \
+               pin6 = (struct in6_addr *)__entry->saddr_v6;    \
+               ipv6_addr_set_v4mapped(saddr, pin6);            \
+               pin6 = (struct in6_addr *)__entry->daddr_v6;    \
+               ipv6_addr_set_v4mapped(daddr, pin6);            \
+       } while (0)
+ 
+ #if IS_ENABLED(CONFIG_IPV6)
+ #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6)         \
+       do {                                                            \
+               if (sk->sk_family == AF_INET6) {                        \
+                       struct in6_addr *pin6;                          \
+                                                                       \
+                       pin6 = (struct in6_addr *)__entry->saddr_v6;    \
+                       *pin6 = saddr6;                                 \
+                       pin6 = (struct in6_addr *)__entry->daddr_v6;    \
+                       *pin6 = daddr6;                                 \
+               } else {                                                \
+                       TP_STORE_V4MAPPED(__entry, saddr, daddr);       \
+               }                                                       \
+       } while (0)
+ #else
+ #define TP_STORE_ADDRS(__entry, saddr, daddr, saddr6, daddr6) \
+       TP_STORE_V4MAPPED(__entry, saddr, daddr)
+ #endif
+ 
  /*
   * tcp event with arguments sk and skb
   *
 
        if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
                dev->mtu -= 8;
  
 +      if (tunnel->parms.collect_md) {
 +              dev->features |= NETIF_F_NETNS_LOCAL;
 +              netif_keep_dst(dev);
 +      }
+       ip6gre_tnl_init_features(dev);
  
        return 0;
  }
        .ndo_get_iflink = ip6_tnl_get_iflink,
  };
  
- #define GRE6_FEATURES (NETIF_F_SG |           \
-                      NETIF_F_FRAGLIST |       \
-                      NETIF_F_HIGHDMA |                \
-                      NETIF_F_HW_CSUM)
- 
 +static int ip6erspan_tap_init(struct net_device *dev)
 +{
 +      struct ip6_tnl *tunnel;
 +      int t_hlen;
 +      int ret;
 +
 +      tunnel = netdev_priv(dev);
 +
 +      tunnel->dev = dev;
 +      tunnel->net = dev_net(dev);
 +      strcpy(tunnel->parms.name, dev->name);
 +
 +      dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
 +      if (!dev->tstats)
 +              return -ENOMEM;
 +
 +      ret = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
 +      if (ret) {
 +              free_percpu(dev->tstats);
 +              dev->tstats = NULL;
 +              return ret;
 +      }
 +
 +      tunnel->tun_hlen = 8;
 +      tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen +
 +                     erspan_hdr_len(tunnel->parms.erspan_ver);
 +      t_hlen = tunnel->hlen + sizeof(struct ipv6hdr);
 +
 +      dev->hard_header_len = LL_MAX_HEADER + t_hlen;
 +      dev->mtu = ETH_DATA_LEN - t_hlen;
 +      if (dev->type == ARPHRD_ETHER)
 +              dev->mtu -= ETH_HLEN;
 +      if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
 +              dev->mtu -= 8;
 +
 +      dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 +      tunnel = netdev_priv(dev);
 +      ip6gre_tnl_link_config(tunnel, 1);
 +
 +      return 0;
 +}
 +
 +static const struct net_device_ops ip6erspan_netdev_ops = {
 +      .ndo_init =             ip6erspan_tap_init,
 +      .ndo_uninit =           ip6gre_tunnel_uninit,
 +      .ndo_start_xmit =       ip6erspan_tunnel_xmit,
 +      .ndo_set_mac_address =  eth_mac_addr,
 +      .ndo_validate_addr =    eth_validate_addr,
 +      .ndo_change_mtu =       ip6_tnl_change_mtu,
 +      .ndo_get_stats64 =      ip_tunnel_get_stats64,
 +      .ndo_get_iflink =       ip6_tnl_get_iflink,
 +};
 +
  static void ip6gre_tap_setup(struct net_device *dev)
  {