@@ -163,8 +163,11 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
163163 bool wildcard ;
164164 bool transparent = true;
165165
166- /* Ignore sockets listening on INADDR_ANY */
167- wildcard = (sk -> sk_state != TCP_TIME_WAIT &&
166+ /* Ignore sockets listening on INADDR_ANY,
167+ * unless XT_SOCKET_NOWILDCARD is set
168+ */
169+ wildcard = (!(info -> flags & XT_SOCKET_NOWILDCARD ) &&
170+ sk -> sk_state != TCP_TIME_WAIT &&
168171 inet_sk (sk )-> inet_rcv_saddr == 0 );
169172
170173 /* Ignore non-transparent sockets,
@@ -197,7 +200,7 @@ socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par)
197200}
198201
199202static bool
200- socket_mt4_v1 (const struct sk_buff * skb , struct xt_action_param * par )
203+ socket_mt4_v1_v2 (const struct sk_buff * skb , struct xt_action_param * par )
201204{
202205 return socket_match (skb , par , par -> matchinfo );
203206}
@@ -259,7 +262,7 @@ extract_icmp6_fields(const struct sk_buff *skb,
259262}
260263
261264static bool
262- socket_mt6_v1 (const struct sk_buff * skb , struct xt_action_param * par )
265+ socket_mt6_v1_v2 (const struct sk_buff * skb , struct xt_action_param * par )
263266{
264267 struct ipv6hdr * iph = ipv6_hdr (skb );
265268 struct udphdr _hdr , * hp = NULL ;
@@ -302,8 +305,11 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
302305 bool wildcard ;
303306 bool transparent = true;
304307
305- /* Ignore sockets listening on INADDR_ANY */
306- wildcard = (sk -> sk_state != TCP_TIME_WAIT &&
308+ /* Ignore sockets listening on INADDR_ANY
309+ * unless XT_SOCKET_NOWILDCARD is set
310+ */
311+ wildcard = (!(info -> flags & XT_SOCKET_NOWILDCARD ) &&
312+ sk -> sk_state != TCP_TIME_WAIT &&
307313 ipv6_addr_any (& inet6_sk (sk )-> rcv_saddr ));
308314
309315 /* Ignore non-transparent sockets,
@@ -331,6 +337,28 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
331337}
332338#endif
333339
340+ static int socket_mt_v1_check (const struct xt_mtchk_param * par )
341+ {
342+ const struct xt_socket_mtinfo1 * info = (struct xt_socket_mtinfo1 * ) par -> matchinfo ;
343+
344+ if (info -> flags & ~XT_SOCKET_FLAGS_V1 ) {
345+ pr_info ("unknown flags 0x%x\n" , info -> flags & ~XT_SOCKET_FLAGS_V1 );
346+ return - EINVAL ;
347+ }
348+ return 0 ;
349+ }
350+
351+ static int socket_mt_v2_check (const struct xt_mtchk_param * par )
352+ {
353+ const struct xt_socket_mtinfo2 * info = (struct xt_socket_mtinfo2 * ) par -> matchinfo ;
354+
355+ if (info -> flags & ~XT_SOCKET_FLAGS_V2 ) {
356+ pr_info ("unknown flags 0x%x\n" , info -> flags & ~XT_SOCKET_FLAGS_V2 );
357+ return - EINVAL ;
358+ }
359+ return 0 ;
360+ }
361+
334362static struct xt_match socket_mt_reg [] __read_mostly = {
335363 {
336364 .name = "socket" ,
@@ -345,7 +373,8 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
345373 .name = "socket" ,
346374 .revision = 1 ,
347375 .family = NFPROTO_IPV4 ,
348- .match = socket_mt4_v1 ,
376+ .match = socket_mt4_v1_v2 ,
377+ .checkentry = socket_mt_v1_check ,
349378 .matchsize = sizeof (struct xt_socket_mtinfo1 ),
350379 .hooks = (1 << NF_INET_PRE_ROUTING ) |
351380 (1 << NF_INET_LOCAL_IN ),
@@ -356,7 +385,32 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
356385 .name = "socket" ,
357386 .revision = 1 ,
358387 .family = NFPROTO_IPV6 ,
359- .match = socket_mt6_v1 ,
388+ .match = socket_mt6_v1_v2 ,
389+ .checkentry = socket_mt_v1_check ,
390+ .matchsize = sizeof (struct xt_socket_mtinfo1 ),
391+ .hooks = (1 << NF_INET_PRE_ROUTING ) |
392+ (1 << NF_INET_LOCAL_IN ),
393+ .me = THIS_MODULE ,
394+ },
395+ #endif
396+ {
397+ .name = "socket" ,
398+ .revision = 2 ,
399+ .family = NFPROTO_IPV4 ,
400+ .match = socket_mt4_v1_v2 ,
401+ .checkentry = socket_mt_v2_check ,
402+ .matchsize = sizeof (struct xt_socket_mtinfo1 ),
403+ .hooks = (1 << NF_INET_PRE_ROUTING ) |
404+ (1 << NF_INET_LOCAL_IN ),
405+ .me = THIS_MODULE ,
406+ },
407+ #ifdef XT_SOCKET_HAVE_IPV6
408+ {
409+ .name = "socket" ,
410+ .revision = 2 ,
411+ .family = NFPROTO_IPV6 ,
412+ .match = socket_mt6_v1_v2 ,
413+ .checkentry = socket_mt_v2_check ,
360414 .matchsize = sizeof (struct xt_socket_mtinfo1 ),
361415 .hooks = (1 << NF_INET_PRE_ROUTING ) |
362416 (1 << NF_INET_LOCAL_IN ),
0 commit comments