강좌 & 팁
데이터 송수신 및 통계정보와 관련된 함수에 대하여 알아 보도록 하겠습니다.
// 고 수준의 재진입을 하지 못하도록 하는 것을 다룹니다. ( 이것은 바텀할프가 비활성화 되는동안에 호출 됩니다.) static netdev_tx_t loopback_xmit(struct sk_buff *skb, struct net_device *dev) { struct pcpu_lstats __percpu *pcpu_lstats; struct pcpu_lstats *lb_stats; int len; // 소켓 버퍼의 owner가 가진 destructor함수가 존재할 경우 이를 호출해주며, // 소켓 버퍼의 owner를 없애주는 역할을 하는 함수이다. skb_orphan(skb); // eth_type_trans()함수는 패킷의 타입을 결정 하고, 프로토콜의 ID를 넘긴다. // 리턴값을 이용 하여 소켓 버퍼의 protocol 값을 설정 하고, dev 에는 // 현재의 네트워크 디바이스 구조체 표시 skb->protocol = eth_type_trans(skb, dev); // per_cup_ptr 함수를 사용하여 바텀할프로 하지 않는다. pcpu_lstats = (void __percpu __force *)dev->ml_priv; lb_stats = this_cpu_ptr(pcpu_lstats); len = skb->len; // 패킷 수신 처리 부분 if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { // 통계정보를 업데이트 하는 부분이다. lb_stats->bytes += len; lb_stats->packets++; } else lb_stats->drops++; return NETDEV_TX_OK; } // loopback 디바이스 드라이버가 관리하는 통계정보를 알려주는 역할을 한다. // net_device구조체의 stats에 할당한 net_device_stats구조체에 통계 정보를 갱신하고 그값을 리턴. static struct net_device_stats *loopback_get_stats(struct net_device *dev) { const struct pcpu_lstats __percpu *pcpu_lstats; struct net_device_stats *stats = &dev->stats; unsigned long bytes = 0; unsigned long packets = 0; unsigned long drops = 0; int i; pcpu_lstats = (void __percpu __force *)dev->ml_priv; for_each_possible_cpu(i) { const struct pcpu_lstats *lb_stats; lb_stats = per_cpu_ptr(pcpu_lstats, i); bytes += lb_stats->bytes; packets += lb_stats->packets; drops += lb_stats->drops; } // 상태 정보 구조체에 값을 갱신 한다. stats->rx_packets = packets; stats->tx_packets = packets; stats->rx_dropped = drops; stats->rx_errors = drops; stats->rx_bytes = bytes; stats->tx_bytes = bytes; return stats; } |