У меня есть следующий код для отмены регистрации и регистрации sip conntrack из ядра 3.18
static void __nf_conntrack_sip_fini(void)
{
int i, j;
for (i = 0; i < ports_c; i++) {
for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
if (sip[i][j].me == NULL)
continue;
nf_conntrack_helper_unregister(&sip[i][j]);
}
}
memset(sip, 0, sizeof(sip));
}
static int __nf_conntrack_sip_init(void)
{
int i, j, ret;
if (ports_c == 0)
ports[ports_c++] = SIP_PORT;
for (i = 0; i < ports_c; i++) {
memset(&sip[i], 0, sizeof(sip[i]));
sip[i][0].tuple.src.l3num = AF_INET;
sip[i][0].tuple.dst.protonum = IPPROTO_UDP;
sip[i][0].help = sip_help_udp;
sip[i][1].tuple.src.l3num = AF_INET;
sip[i][1].tuple.dst.protonum = IPPROTO_TCP;
sip[i][1].help = sip_help_tcp;
sip[i][2].tuple.src.l3num = AF_INET6;
sip[i][2].tuple.dst.protonum = IPPROTO_UDP;
sip[i][2].help = sip_help_udp;
sip[i][3].tuple.src.l3num = AF_INET6;
sip[i][3].tuple.dst.protonum = IPPROTO_TCP;
sip[i][3].help = sip_help_tcp;
for (j = 0; j < ARRAY_SIZE(sip[i]); j++) {
sip[i][j].data_len = sizeof(struct nf_ct_sip_master);
sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
sip[i][j].expect_policy = sip_exp_policy;
sip[i][j].expect_class_max = SIP_EXPECT_MAX;
sip[i][j].me = THIS_MODULE;
if (ports[i] == SIP_PORT)
sprintf(sip[i][j].name, "sip");
else
sprintf(sip[i][j].name, "sip-%u", i);
pr_debug("port #%u: %u\n", i, ports[i]);
ret = nf_conntrack_helper_register(&sip[i][j]);
if (ret) {
printk(KERN_ERR "nf_ct_sip: failed to register"
" helper for pf: %u port: %u i=%d\n",
sip[i][j].tuple.src.l3num, ports[i], i);
__nf_conntrack_sip_fini();
return ret;
}
}
}
return 0;
}
Я разработал следующий код, чтобы перезапустить зарегистрированный sip conntrack с тем же самым первым портом
static void nf_conntrack_sip_restart(void)
{
//here ports[] = {5060, 0}
__nf_conntrack_sip_fini();
memcpy(ports,newports,sizeof(ports));
//here ports[] = {5060, 5555}
__nf_conntrack_sip_init(); // <---- It fails
}
когда я запускаю эту функцию перезапуска из пользовательского пространства, регистр регистра нового массива портов
Если я использую другие порты, то он работает:
static void nf_conntrack_sip_restart(void)
{
//here ports[] = {5060, 0}
__nf_conntrack_sip_fini();
memcpy(ports,newports,sizeof(ports));
//here ports[] = {5061, 5555}
__nf_conntrack_sip_init(); // <---- It works
}
Что мне не хватает?
Здесь после всего исходного кода файла nf_conntrack_sip.c с моими изменениями: http://vpaste.net/PgUVD
Чтобы увидеть мои изменения, вы можете сделать diff с исходным кодом источника linux 3.18