Commit 180cf72f authored by holger@eitzenberger.org's avatar holger@eitzenberger.org Committed by Pablo Neira Ayuso

netfilter: nf_ct_sip: consolidate NAT hook functions

There are currently seven different NAT hooks used in both
nf_conntrack_sip and nf_nat_sip, each of the hooks is exported in
nf_conntrack_sip, then set from the nf_nat_sip NAT helper.

And because each of them is exported there is quite some overhead
introduced due of this.

By introducing nf_nat_sip_hooks I am able to reduce both text/data
somewhat.  For nf_conntrack_sip e. g. I get

        text             data              bss              dec
old    15243             5256               32            20531
new    15010             5192               32            20234
Signed-off-by: default avatarHolger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent afff14f6
...@@ -107,55 +107,64 @@ enum sdp_header_types { ...@@ -107,55 +107,64 @@ enum sdp_header_types {
SDP_HDR_MEDIA, SDP_HDR_MEDIA,
}; };
extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, struct nf_nat_sip_hooks {
unsigned int protoff, unsigned int (*msg)(struct sk_buff *skb,
unsigned int dataoff, unsigned int protoff,
const char **dptr, unsigned int dataoff,
unsigned int *datalen); const char **dptr,
extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, unsigned int *datalen);
unsigned int protoff, s16 off);
extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, void (*seq_adjust)(struct sk_buff *skb,
unsigned int protoff, unsigned int protoff, s16 off);
unsigned int dataoff,
const char **dptr, unsigned int (*expect)(struct sk_buff *skb,
unsigned int *datalen, unsigned int protoff,
struct nf_conntrack_expect *exp, unsigned int dataoff,
unsigned int matchoff, const char **dptr,
unsigned int matchlen); unsigned int *datalen,
extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, struct nf_conntrack_expect *exp,
unsigned int protoff, unsigned int matchoff,
unsigned int dataoff, unsigned int matchlen);
const char **dptr,
unsigned int *datalen, unsigned int (*sdp_addr)(struct sk_buff *skb,
unsigned int sdpoff, unsigned int protoff,
enum sdp_header_types type, unsigned int dataoff,
enum sdp_header_types term, const char **dptr,
const union nf_inet_addr *addr); unsigned int *datalen,
extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int sdpoff,
unsigned int protoff, enum sdp_header_types type,
unsigned int dataoff, enum sdp_header_types term,
const char **dptr, const union nf_inet_addr *addr);
unsigned int *datalen,
unsigned int matchoff, unsigned int (*sdp_port)(struct sk_buff *skb,
unsigned int matchlen, unsigned int protoff,
u_int16_t port); unsigned int dataoff,
extern unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, const char **dptr,
unsigned int protoff, unsigned int *datalen,
unsigned int dataoff, unsigned int matchoff,
const char **dptr, unsigned int matchlen,
unsigned int *datalen, u_int16_t port);
unsigned int sdpoff,
const union nf_inet_addr *addr); unsigned int (*sdp_session)(struct sk_buff *skb,
extern unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int protoff,
unsigned int protoff, unsigned int dataoff,
unsigned int dataoff, const char **dptr,
const char **dptr, unsigned int *datalen,
unsigned int *datalen, unsigned int sdpoff,
struct nf_conntrack_expect *rtp_exp, const union nf_inet_addr *addr);
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff, unsigned int (*sdp_media)(struct sk_buff *skb,
unsigned int medialen, unsigned int protoff,
union nf_inet_addr *rtp_addr); unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff,
unsigned int medialen,
union nf_inet_addr *rtp_addr);
};
extern const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
extern int ct_sip_parse_request(const struct nf_conn *ct, extern int ct_sip_parse_request(const struct nf_conn *ct,
const char *dptr, unsigned int datalen, const char *dptr, unsigned int datalen,
......
...@@ -52,66 +52,8 @@ module_param(sip_direct_media, int, 0600); ...@@ -52,66 +52,8 @@ module_param(sip_direct_media, int, 0600);
MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
"endpoints only (default 1)"); "endpoints only (default 1)");
unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int protoff, const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
unsigned int dataoff, const char **dptr, EXPORT_SYMBOL_GPL(nf_nat_sip_hooks);
unsigned int *datalen) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, unsigned int protoff,
s16 off) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook);
unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
unsigned int protoff,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *exp,
unsigned int matchoff,
unsigned int matchlen) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int protoff,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int sdpoff,
enum sdp_header_types type,
enum sdp_header_types term,
const union nf_inet_addr *addr)
__read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int protoff,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int matchoff,
unsigned int matchlen,
u_int16_t port) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
unsigned int protoff,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
unsigned int sdpoff,
const union nf_inet_addr *addr)
__read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int protoff,
unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff,
unsigned int medialen,
union nf_inet_addr *rtp_addr)
__read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_media_hook);
static int string_len(const struct nf_conn *ct, const char *dptr, static int string_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift) const char *limit, int *shift)
...@@ -914,8 +856,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, ...@@ -914,8 +856,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
int direct_rtp = 0, skip_expect = 0, ret = NF_DROP; int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
u_int16_t base_port; u_int16_t base_port;
__be16 rtp_port, rtcp_port; __be16 rtp_port, rtcp_port;
typeof(nf_nat_sdp_port_hook) nf_nat_sdp_port; const struct nf_nat_sip_hooks *hooks;
typeof(nf_nat_sdp_media_hook) nf_nat_sdp_media;
saddr = NULL; saddr = NULL;
if (sip_direct_media) { if (sip_direct_media) {
...@@ -972,9 +913,9 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, ...@@ -972,9 +913,9 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
rtcp_port = htons(base_port + 1); rtcp_port = htons(base_port + 1);
if (direct_rtp) { if (direct_rtp) {
nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
if (nf_nat_sdp_port && if (hooks &&
!nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen, !hooks->sdp_port(skb, protoff, dataoff, dptr, datalen,
mediaoff, medialen, ntohs(rtp_port))) mediaoff, medialen, ntohs(rtp_port)))
goto err1; goto err1;
} }
...@@ -996,10 +937,10 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, ...@@ -996,10 +937,10 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr, nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
IPPROTO_UDP, NULL, &rtcp_port); IPPROTO_UDP, NULL, &rtcp_port);
nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp) if (hooks && ct->status & IPS_NAT_MASK && !direct_rtp)
ret = nf_nat_sdp_media(skb, protoff, dataoff, dptr, datalen, ret = hooks->sdp_media(skb, protoff, dataoff, dptr,
rtp_exp, rtcp_exp, datalen, rtp_exp, rtcp_exp,
mediaoff, medialen, daddr); mediaoff, medialen, daddr);
else { else {
if (nf_ct_expect_related(rtp_exp) == 0) { if (nf_ct_expect_related(rtp_exp) == 0) {
...@@ -1053,13 +994,12 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff, ...@@ -1053,13 +994,12 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
unsigned int caddr_len, maddr_len; unsigned int caddr_len, maddr_len;
unsigned int i; unsigned int i;
union nf_inet_addr caddr, maddr, rtp_addr; union nf_inet_addr caddr, maddr, rtp_addr;
const struct nf_nat_sip_hooks *hooks;
unsigned int port; unsigned int port;
const struct sdp_media_type *t; const struct sdp_media_type *t;
int ret = NF_ACCEPT; int ret = NF_ACCEPT;
typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr;
typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
/* Find beginning of session description */ /* Find beginning of session description */
if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen, if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
...@@ -1127,10 +1067,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff, ...@@ -1127,10 +1067,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
} }
/* Update media connection address if present */ /* Update media connection address if present */
if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { if (maddr_len && hooks && ct->status & IPS_NAT_MASK) {
ret = nf_nat_sdp_addr(skb, protoff, dataoff, ret = hooks->sdp_addr(skb, protoff, dataoff,
dptr, datalen, mediaoff, dptr, datalen, mediaoff,
SDP_HDR_CONNECTION, SDP_HDR_MEDIA, SDP_HDR_CONNECTION,
SDP_HDR_MEDIA,
&rtp_addr); &rtp_addr);
if (ret != NF_ACCEPT) { if (ret != NF_ACCEPT) {
nf_ct_helper_log(skb, ct, "cannot mangle SDP"); nf_ct_helper_log(skb, ct, "cannot mangle SDP");
...@@ -1141,10 +1082,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff, ...@@ -1141,10 +1082,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
} }
/* Update session connection and owner addresses */ /* Update session connection and owner addresses */
nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) if (hooks && ct->status & IPS_NAT_MASK)
ret = nf_nat_sdp_session(skb, protoff, dataoff, ret = hooks->sdp_session(skb, protoff, dataoff,
dptr, datalen, sdpoff, &rtp_addr); dptr, datalen, sdpoff,
&rtp_addr);
return ret; return ret;
} }
...@@ -1244,11 +1186,11 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, ...@@ -1244,11 +1186,11 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
unsigned int matchoff, matchlen; unsigned int matchoff, matchlen;
struct nf_conntrack_expect *exp; struct nf_conntrack_expect *exp;
union nf_inet_addr *saddr, daddr; union nf_inet_addr *saddr, daddr;
const struct nf_nat_sip_hooks *hooks;
__be16 port; __be16 port;
u8 proto; u8 proto;
unsigned int expires = 0; unsigned int expires = 0;
int ret; int ret;
typeof(nf_nat_sip_expect_hook) nf_nat_sip_expect;
/* Expected connections can not register again. */ /* Expected connections can not register again. */
if (ct->status & IPS_EXPECTED) if (ct->status & IPS_EXPECTED)
...@@ -1311,10 +1253,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, ...@@ -1311,10 +1253,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
exp->helper = nfct_help(ct)->helper; exp->helper = nfct_help(ct)->helper;
exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK) if (hooks && ct->status & IPS_NAT_MASK)
ret = nf_nat_sip_expect(skb, protoff, dataoff, dptr, datalen, ret = hooks->expect(skb, protoff, dataoff, dptr, datalen,
exp, matchoff, matchlen); exp, matchoff, matchlen);
else { else {
if (nf_ct_expect_related(exp) != 0) { if (nf_ct_expect_related(exp) != 0) {
nf_ct_helper_log(skb, ct, "cannot add expectation"); nf_ct_helper_log(skb, ct, "cannot add expectation");
...@@ -1517,7 +1459,7 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct, ...@@ -1517,7 +1459,7 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
unsigned int protoff, unsigned int dataoff, unsigned int protoff, unsigned int dataoff,
const char **dptr, unsigned int *datalen) const char **dptr, unsigned int *datalen)
{ {
typeof(nf_nat_sip_hook) nf_nat_sip; const struct nf_nat_sip_hooks *hooks;
int ret; int ret;
if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
...@@ -1526,9 +1468,9 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct, ...@@ -1526,9 +1468,9 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
ret = process_sip_response(skb, protoff, dataoff, dptr, datalen); ret = process_sip_response(skb, protoff, dataoff, dptr, datalen);
if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
nf_nat_sip = rcu_dereference(nf_nat_sip_hook); hooks = rcu_dereference(nf_nat_sip_hooks);
if (nf_nat_sip && !nf_nat_sip(skb, protoff, dataoff, if (hooks && !hooks->msg(skb, protoff, dataoff,
dptr, datalen)) { dptr, datalen)) {
nf_ct_helper_log(skb, ct, "cannot NAT SIP message"); nf_ct_helper_log(skb, ct, "cannot NAT SIP message");
ret = NF_DROP; ret = NF_DROP;
} }
...@@ -1548,7 +1490,6 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, ...@@ -1548,7 +1490,6 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
s16 diff, tdiff = 0; s16 diff, tdiff = 0;
int ret = NF_ACCEPT; int ret = NF_ACCEPT;
bool term; bool term;
typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
if (ctinfo != IP_CT_ESTABLISHED && if (ctinfo != IP_CT_ESTABLISHED &&
ctinfo != IP_CT_ESTABLISHED_REPLY) ctinfo != IP_CT_ESTABLISHED_REPLY)
...@@ -1612,9 +1553,11 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, ...@@ -1612,9 +1553,11 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
} }
if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook); const struct nf_nat_sip_hooks *hooks;
if (nf_nat_sip_seq_adjust)
nf_nat_sip_seq_adjust(skb, protoff, tdiff); hooks = rcu_dereference(nf_nat_sip_hooks);
if (hooks)
hooks->seq_adjust(skb, protoff, tdiff);
} }
return ret; return ret;
......
...@@ -625,33 +625,26 @@ static struct nf_ct_helper_expectfn sip_nat = { ...@@ -625,33 +625,26 @@ static struct nf_ct_helper_expectfn sip_nat = {
static void __exit nf_nat_sip_fini(void) static void __exit nf_nat_sip_fini(void)
{ {
RCU_INIT_POINTER(nf_nat_sip_hook, NULL); RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL);
RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
nf_ct_helper_expectfn_unregister(&sip_nat); nf_ct_helper_expectfn_unregister(&sip_nat);
synchronize_rcu(); synchronize_rcu();
} }
static const struct nf_nat_sip_hooks sip_hooks = {
.msg = nf_nat_sip,
.seq_adjust = nf_nat_sip_seq_adjust,
.expect = nf_nat_sip_expect,
.sdp_addr = nf_nat_sdp_addr,
.sdp_port = nf_nat_sdp_port,
.sdp_session = nf_nat_sdp_session,
.sdp_media = nf_nat_sdp_media,
};
static int __init nf_nat_sip_init(void) static int __init nf_nat_sip_init(void)
{ {
BUG_ON(nf_nat_sip_hook != NULL); BUG_ON(nf_nat_sip_hooks != NULL);
BUG_ON(nf_nat_sip_seq_adjust_hook != NULL); RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks);
BUG_ON(nf_nat_sip_expect_hook != NULL);
BUG_ON(nf_nat_sdp_addr_hook != NULL);
BUG_ON(nf_nat_sdp_port_hook != NULL);
BUG_ON(nf_nat_sdp_session_hook != NULL);
BUG_ON(nf_nat_sdp_media_hook != NULL);
RCU_INIT_POINTER(nf_nat_sip_hook, nf_nat_sip);
RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, nf_nat_sip_seq_adjust);
RCU_INIT_POINTER(nf_nat_sip_expect_hook, nf_nat_sip_expect);
RCU_INIT_POINTER(nf_nat_sdp_addr_hook, nf_nat_sdp_addr);
RCU_INIT_POINTER(nf_nat_sdp_port_hook, nf_nat_sdp_port);
RCU_INIT_POINTER(nf_nat_sdp_session_hook, nf_nat_sdp_session);
RCU_INIT_POINTER(nf_nat_sdp_media_hook, nf_nat_sdp_media);
nf_ct_helper_expectfn_register(&sip_nat); nf_ct_helper_expectfn_register(&sip_nat);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment