티스토리 뷰



ip6tables롸 64bit kernel 호환성을 맞추며 공부하다 보니 이렇게 포스팅을 하게 되었습니다. ip6tables에서 사용되는 getsockopt와 setsockopt는 kerenl 내에 nf_sockopt_ops 구조체로 받아지는데, 구조체 형태는 아래와 같습니다. (linux-3.0.4 기준)

static struct nf_sockopt_ops ip6t_sockopts = {
    .pf             = PF_INET6,
    .set_optmin     = IP6T_BASE_CTL,
    .set_optmax     = IP6T_SO_SET_MAX+1,
    .set            = do_ip6t_set_ctl,
#ifdef CONFIG_COMPAT
    .compat_set     = compat_do_ip6t_set_ctl,
#endif
    .get_optmin     = IP6T_BASE_CTL,
    .get_optmax     = IP6T_SO_GET_MAX+1,
    .get            = do_ip6t_get_ctl,
#ifdef CONFIG_COMPAT
    .compat_get     = compat_do_ip6t_get_ctl,
#endif
    .owner          = THIS_MODULE,
};
이 구조체는 부팅되는 시점에 ip6_tables_init 함수에서 register에 등록이 됩니다.
/* Register setsockopt */
ret = nf_register_sockopt(&ip6t_sockopts);
정상적으로 register에 등록이 되면 부팅이후 dmesg를 통해 아래와 같은 문구를 만날 수 있습니다.
$ dmesg | grep tables
ip_tables: (C) 2000-2006 Netfilter Core Team
arp_tables: (C) 2002 David S. Miller
ip6_tables: (C) 2000-2006 Netfilter Core Team

이렇게 register에 sockopt가 등록이 되면, ip6tables에서 getsockopt, setsockopt가 실행이 될때, Kernel의 compat_nf_sockopt 함수는 register에 등록된 sockopt를 찾고(nf_sockopt_find 함수) 찾게된 경우 해당 함수 포인터를 실행시킵니다. (보통 compat이 붙은 함수는 64bit에서 수행되는 함수입니다) compat_nf_sockopt의 형태는 아래와 같습니다.

#ifdef CONFIG_COMPAT
static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
                             char __user *opt, int *len, int get)
{                       
    struct nf_sockopt_ops *ops;
    int ret;

    ops = nf_sockopt_find(sk, pf, val, get);
    if (IS_ERR(ops))                        
        return PTR_ERR(ops); 

    if (get) {              
        if (ops->compat_get)            
            ret = ops->compat_get(sk, val, opt, len);
        else    
            ret = ops->get(sk, val, opt, len);
    } else {
        if (ops->compat_set)
            ret = ops->compat_set(sk, val, opt, *len);
        else
            ret = ops->set(sk, val, opt, *len);
        }
    module_put(ops->owner);
    return ret;
}


정리하면, 실제 동작을 예로 들어 ip6tables에서 getsockopt나 setsockopt가 실행이 되었다면 Kernel은 system call인 sys_setsockopt로 iptables의 명령을 받고 compat_do_ip6_get_ctl 함수가 최종적으로 find되어 동작 되는것 입니다.



'개발 > Linux' 카테고리의 다른 글

Kernel ipt_get_entries struct .. size  (0) 2011.12.04
__alignof__, aligned 매크로  (0) 2011.12.02
64bit kernel + 32bit iptables (Application)  (0) 2011.11.30
find command  (0) 2011.11.29
비용이 낮은 연산자 선택 [%->&, / -> >>]  (0) 2011.11.20
댓글
최근에 올라온 글
최근에 달린 댓글
글 보관함
Total
Today
Yesterday