bb318e4623a3f8174f244d8deef6adea0866d761
1 #define KMSG_COMPONENT "IPVS"
2 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
4 #include <linux/module.h>
5 #include <linux/kernel.h>
8 #include <net/netfilter/nf_conntrack.h>
9 #include <linux/netfilter/nf_conntrack_sip.h>
11 #ifdef CONFIG_IP_VS_DEBUG
12 static const char *ip_vs_dbg_callid(char *buf
, size_t buf_len
,
13 const char *callid
, size_t callid_len
,
17 size_t len
= min3(max_len
, callid_len
, buf_len
- *idx
- 1);
18 memcpy(buf
+ *idx
, callid
, len
);
21 return buf
+ *idx
- len
;
24 #define IP_VS_DEBUG_CALLID(callid, len) \
25 ip_vs_dbg_callid(ip_vs_dbg_buf, sizeof(ip_vs_dbg_buf), \
26 callid, len, &ip_vs_dbg_idx)
29 static int get_callid(const char *dptr
, unsigned int dataoff
,
31 unsigned int *matchoff
, unsigned int *matchlen
)
35 int ret
= ct_sip_get_header(NULL
, dptr
, dataoff
, datalen
,
36 SIP_HDR_CALL_ID
, matchoff
,
45 /* Too large is useless */
46 if (*matchlen
> IP_VS_PEDATA_MAXLEN
)
49 /* SIP headers are always followed by a line terminator */
50 if (*matchoff
+ *matchlen
== datalen
)
53 /* RFC 2543 allows lines to be terminated with CR, LF or CRLF,
54 * RFC 3261 allows only CRLF, we support both. */
55 if (*(dptr
+ *matchoff
+ *matchlen
) != '\r' &&
56 *(dptr
+ *matchoff
+ *matchlen
) != '\n')
59 IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n",
60 IP_VS_DEBUG_CALLID(dptr
+ *matchoff
, *matchlen
),
66 ip_vs_sip_fill_param(struct ip_vs_conn_param
*p
, struct sk_buff
*skb
)
68 struct ip_vs_iphdr iph
;
69 unsigned int dataoff
, datalen
, matchoff
, matchlen
;
73 ip_vs_fill_iph_skb(p
->af
, skb
, &iph
);
75 /* Only useful with UDP */
76 if (iph
.protocol
!= IPPROTO_UDP
)
78 /* todo: IPv6 fragments:
79 * I think this only should be done for the first fragment. /HS
81 dataoff
= iph
.len
+ sizeof(struct udphdr
);
83 if (dataoff
>= skb
->len
)
85 retc
= skb_linearize(skb
);
88 dptr
= skb
->data
+ dataoff
;
89 datalen
= skb
->len
- dataoff
;
91 if (get_callid(dptr
, 0, datalen
, &matchoff
, &matchlen
))
94 /* N.B: pe_data is only set on success,
95 * this allows fallback to the default persistence logic on failure
97 p
->pe_data
= kmemdup(dptr
+ matchoff
, matchlen
, GFP_ATOMIC
);
101 p
->pe_data_len
= matchlen
;
106 static bool ip_vs_sip_ct_match(const struct ip_vs_conn_param
*p
,
107 struct ip_vs_conn
*ct
)
112 if (ct
->af
== p
->af
&&
113 ip_vs_addr_equal(p
->af
, p
->caddr
, &ct
->caddr
) &&
114 /* protocol should only be IPPROTO_IP if
115 * d_addr is a fwmark */
116 ip_vs_addr_equal(p
->protocol
== IPPROTO_IP
? AF_UNSPEC
: p
->af
,
117 p
->vaddr
, &ct
->vaddr
) &&
118 ct
->vport
== p
->vport
&&
119 ct
->flags
& IP_VS_CONN_F_TEMPLATE
&&
120 ct
->protocol
== p
->protocol
&&
121 ct
->pe_data
&& ct
->pe_data_len
== p
->pe_data_len
&&
122 !memcmp(ct
->pe_data
, p
->pe_data
, p
->pe_data_len
))
125 IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n",
126 ip_vs_proto_name(p
->protocol
),
127 IP_VS_DEBUG_CALLID(p
->pe_data
, p
->pe_data_len
),
128 IP_VS_DBG_ADDR(p
->af
, p
->vaddr
), ntohs(p
->vport
),
129 ret
? "hit" : "not hit");
134 static u32
ip_vs_sip_hashkey_raw(const struct ip_vs_conn_param
*p
,
135 u32 initval
, bool inverse
)
137 return jhash(p
->pe_data
, p
->pe_data_len
, initval
);
140 static int ip_vs_sip_show_pe_data(const struct ip_vs_conn
*cp
, char *buf
)
142 memcpy(buf
, cp
->pe_data
, cp
->pe_data_len
);
143 return cp
->pe_data_len
;
146 static struct ip_vs_pe ip_vs_sip_pe
=
149 .refcnt
= ATOMIC_INIT(0),
150 .module
= THIS_MODULE
,
151 .n_list
= LIST_HEAD_INIT(ip_vs_sip_pe
.n_list
),
152 .fill_param
= ip_vs_sip_fill_param
,
153 .ct_match
= ip_vs_sip_ct_match
,
154 .hashkey_raw
= ip_vs_sip_hashkey_raw
,
155 .show_pe_data
= ip_vs_sip_show_pe_data
,
158 static int __init
ip_vs_sip_init(void)
160 return register_ip_vs_pe(&ip_vs_sip_pe
);
163 static void __exit
ip_vs_sip_cleanup(void)
165 unregister_ip_vs_pe(&ip_vs_sip_pe
);
169 module_init(ip_vs_sip_init
);
170 module_exit(ip_vs_sip_cleanup
);
171 MODULE_LICENSE("GPL");