dump struct sw_flow from vport/datapath

本文通过使用SystemTap工具跟踪openvswitch模块中的ovs_vport_receive函数,详细展示了函数调用流程及关键数据结构,包括vport、datapath、table_instance等,帮助读者深入理解Open vSwitch的数据包处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

+ cat /root/stap/ovs_vport_receive.stp
#!/usr/local/bin/stap


global start
function timestamp:long() { return gettimeofday_us() - start }
probe begin { start = gettimeofday_us() }


probe module("openvswitch").function("ovs_vport_receive")
{
        print_backtrace()
        printf("parms: %s\n", $$parms);
        printf("execname: %s\n", execname());
        printf("ts: %d\n", timestamp()/1000000);
        print_ubacktrace()
}
+ cd /root/stap
+ chmod +x /root/stap/ovs_vport_receive.stp
+ stap -d vhost -d vhost_net -d tun -d kernel -d openvswitch -d vport_vxlan -d vxlan -d /usr/lib64/libpthread-2.17.so -d /usr/local/sbin/ovs-vswitchd -d /usr/lib64/libc-2.17.so /root/stap/ovs_vport_receive.stp
 0xffffffffa0972260 : ovs_vport_receive+0x0/0xd0 [openvswitch]
 0xffffffffa0972e7e : netdev_port_receive+0xae/0x120 [openvswitch]
 0xffffffffa0972f41 : netdev_frame_hook+0x51/0x60 [openvswitch]
 0xffffffff8161839c : __netif_receive_skb_core+0x1dc/0xa00 [kernel]
 0xffffffff81618bd8 : __netif_receive_skb+0x18/0x60 [kernel]
 0xffffffff81618c60 : netif_receive_skb_internal+0x40/0xb0 [kernel]
 0xffffffff81618cec : netif_receive_skb+0x1c/0x70 [kernel]
 0xffffffffa0945f9f : tun_get_user+0x45f/0x800 [tun]
 0xffffffffa094638e : tun_sendmsg+0x4e/0x70 [tun]
 0xffffffffa09bf932 : handle_tx+0x282/0x540 [vhost_net]
 0xffffffffa09bfc25 : handle_tx_kick+0x15/0x20 [vhost_net]
 0xffffffffa09adcfe : vhost_worker+0x9e/0xf0 [vhost]
 0xffffffff810b0711 : kthread+0x101/0x140 [kernel]
 0xffffffff8173975c : ret_from_fork+0x2c/0x40 [kernel]
 0x0 (inexact)
parms: vport=0xffff88065fa54180 skb=0xffff8805d5eaaa00 tun_info=0x0


crash> vport 0xffff88065fa54180
struct vport {
  dev = 0xffff88061ec80000,
  dp = 0xffff8806628b6600,
  upcall_portids = 0xffff880c42c46840,
  port_no = 6,
  hash_node = {
    next = 0x0,
    pprev = 0xffff880620451018
  },
  dp_hash_node = {
    next = 0x0,
    pprev = 0xffff8806204a2030
  },
  ops = 0xffffffffa097d460,
  detach_list = {
    next = 0x0,
    prev = 0x0
  },
  rcu = {
    next = 0x0,
    func = 0x0
  }
}

crash> datapath 0xffff8806628b6600
struct datapath {
  rcu = {
    next = 0x0,
    func = 0x0
  },
  list_node = {
    next = 0xffff8806335815c0,
    prev = 0xffff8806335815c0
  },
  table = {
    ti = 0xffff880c436bcc40,
    ufid_ti = 0xffff880c1e59e840,
    mask_list = {
      next = 0x60f398810000,
      prev = 0xffff880c437d2900
    },
    last_rehash = 4641435406,
    count = 1,
    ufid_count = 1
  },
  ports = 0xffff8806204a2000,
  stats_percpu = 0x60f398805f00,
  net = {
    net = 0xffffffff81d1f880 <init_net>
  },
  user_features = 3,
  max_headroom = 84
}

crash> table_instance 0xffff880c436bcc40
struct table_instance {
  buckets = 0xffff88065d4ab000,
  n_buckets = 1024,
  rcu = {
    next = 0xffffffffffffffff,
    func = 0xffffffffffffffff
  },
  node_ver = 1,
  hash_seed = 3405276875,
  keep_flows = false
}
crash> flex_array 0xffff88065d4ab000
struct flex_array {
  {
    {
      element_size = 8,
      total_nr_elements = 1024,
      elems_per_part = 512,
      reciprocal_elems = {
        m = 1,
        sh1 = 1 '\001',
        sh2 = 8 '\b'
      },
      parts = 0xffff88065d4ab018
    },
...

crash> rd  0xffff88065d4ab018 2
ffff88065d4ab018:  ffff88065d4a8000 ffff88065d4af000   ..J]......J]....

crash> rd ffff88065d4a8000 512
...
ffff88065d4a82d0:  0000000000000000 ffff88061b303660   ........`60.....
...

crash>  sw_flow -o
struct sw_flow {
    [0] struct callback_head rcu;
        struct {
            struct hlist_node node[2];
            u32 hash;
   [16] } flow_table;
        struct {
            struct hlist_node node[2];
            u32 hash;
   [56] } ufid_table;
   [96] int stats_last_writer;
  [104] struct sw_flow_key key;
  [568] struct sw_flow_id id;
  [592] struct sw_flow_mask *mask;
  [600] struct sw_flow_actions *sf_acts;
  [608] struct flow_stats *stats[];
}
SIZE: 608
ffff88061b303640 = ffff88061b303660 - 0x20
crash> sw_flow ffff88061b303640
struct sw_flow {
  rcu = {
    next = 0x0,
    func = 0x0
  },
  flow_table = {
    node = {{
        next = 0x0,
        pprev = 0x0
      }, {
        next = 0x0,
        pprev = 0xffff88065d4a82d8
      }},
    hash = 2181709571
  },
  ufid_table = {
    node = {{
        next = 0x0,
        pprev = 0xffff880637011d70
      }, {
        next = 0x0,
        pprev = 0x0
      }},
    hash = 3222370491
  },
  stats_last_writer = 10,
  key = {
    tun_opts = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
    tun_opts_len = 0 '\000',
    tun_key = {
      tun_id = 0,
      u = {
        ipv4 = {
          src = 0,
          dst = 0
        },
        ipv6 = {
          src = {
            in6_u = {
              u6_addr8 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
              u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
              u6_addr32 = {0, 0, 0, 0}
            }
          },
          dst = {
            in6_u = {
              u6_addr8 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
              u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
              u6_addr32 = {0, 0, 0, 0}
            }
          }
        }
      },
      tun_flags = 0,
      tos = 0 '\000',
      ttl = 0 '\000',
      label = 0,
      tp_src = 0,
      tp_dst = 0
    },
    phy = {
      priority = 0,
      skb_mark = 0,
      in_port = 6
    },
    mac_proto = 1 '\001',
    tun_proto = 0 '\000',
    ovs_flow_hash = 0,
    recirc_id = 0,
    eth = {
      src = "\000\000\000\000\000",
      dst = "\000\000\000\000\000",
      vlan = {
        tpid = 0,
        tci = 0
      },
      cvlan = {
        tpid = 0,
        tci = 0
      },
      type = 1544
    },
    {
      mpls = {
        top_lse = 0
      },
      ip = {
        proto = 0 '\000',
        tos = 0 '\000',
        ttl = 0 '\000',
        frag = 0 '\000'
      }
    },
    tp = {
      src = 0,
      dst = 0,
      flags = 0
    },
    {
      ipv4 = {
        addr = {
          src = 0,
          dst = 0
        },
        arp = {
          sha = "\000\000\000\000\000",
          tha = "\000\000\000\000\000"
        }
      },
      ipv6 = {
        addr = {
          src = {
            in6_u = {
              u6_addr8 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
              u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
              u6_addr32 = {0, 0, 0, 0}
            }
          },
          dst = {
            in6_u = {
              u6_addr8 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
              u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
              u6_addr32 = {0, 0, 0, 0}
            }
          }
        },
        label = 0,
        nd = {
          target = {
            in6_u = {
              u6_addr8 = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
              u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
              u6_addr32 = {0, 0, 0, 0}
            }
          },
          sll = "\000\000\000\000\000",
          tll = "\000\000\000\000\000"
        }
      }
    },
    ct = {
      zone = 0,
      mark = 0,
      state = 0 '\000',
      labels = {
        ct_labels = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
      }
    }
  },
  id = {
    ufid_len = 16,
    {
      ufid = {964579198, 1219776320, 2588231175, 885363074},
      unmasked_key = 0x48b44f40397e4f7e
    }
  },
  mask = 0xffff880bf0f13400,
  sf_acts = 0xffff8805d5ea7d60,
  stats = 0xffff88061b3038a0
}


分析这个结构体具体分析这个结构体 具体解释这个结构体 struct dp_netdev_flow { const struct flow flow; /* Unmasked flow that created this entry. */ /* Hash table index by unmasked flow. */ const struct cmap_node node; /* In owning dp_netdev_pmd_thread's */ /* 'flow_table'. */ const struct cmap_node mark_node; /* In owning flow_mark's mark_to_flow */ const ovs_u128 ufid; /* Unique flow identifier. */ const ovs_u128 mega_ufid; /* Unique mega flow identifier. */ const unsigned pmd_id; /* The 'core_id' of pmd thread owning this */ /* flow. */ /* Number of references. * The classifier owns one reference. * Any thread trying to keep a rule from being freed should hold its own * reference. */ struct ovs_refcount ref_cnt; bool dead; uint32_t mark; /* Unique flow mark assigned to a flow */ /* Statistics. */ struct dp_netdev_flow_stats stats; /* Statistics and attributes received from the netdev offload provider. */ atomic_int netdev_flow_get_result; struct dp_netdev_flow_stats last_stats; struct dp_netdev_flow_attrs last_attrs; /* Actions. */ OVSRCU_TYPE(struct dp_netdev_actions *) actions; /* While processing a group of input packets, the datapath uses the next * member to store a pointer to the output batch for the flow. It is * reset after the batch has been sent out (See dp_netdev_queue_batches(), * packet_batch_per_flow_init() and packet_batch_per_flow_execute()). */ struct packet_batch_per_flow *batch; /* Packet classification. */ char *dp_extra_info; /* String to return in a flow dump/get. */ struct dpcls_rule cr; /* In owning dp_netdev's 'cls'. */ /* 'cr' must be the last member. */ };
06-06
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值