net/netfilter: Add filter table in iptables.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
f7181676b7
commit
9637c10696
@ -58,6 +58,10 @@
|
||||
#define IPT_INV_PROTO XT_INV_PROTO
|
||||
#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */
|
||||
|
||||
/* Values for "inv" field for struct ipt_icmp. */
|
||||
|
||||
#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */
|
||||
|
||||
/* Standard return verdict, or do jump. */
|
||||
|
||||
#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
|
||||
@ -78,8 +82,10 @@
|
||||
(entry) = (FAR struct ipt_entry *) \
|
||||
((FAR uint8_t *)(entry) + (entry)->next_offset))
|
||||
|
||||
/* Get pointer to target from an entry pointer. */
|
||||
/* Get pointer to match / target from an entry pointer. */
|
||||
|
||||
#define IPT_MATCH(e) \
|
||||
((FAR struct xt_entry_match *)((FAR struct ipt_entry *)(e) + 1))
|
||||
#define IPT_TARGET(e) \
|
||||
((FAR struct xt_entry_target *)((FAR uint8_t *)(e) + (e)->target_offset))
|
||||
|
||||
@ -88,9 +94,10 @@
|
||||
#define IPT_FILL_ENTRY(e, target_name) \
|
||||
do \
|
||||
{ \
|
||||
(e)->entry.target_offset = sizeof((e)->entry); \
|
||||
(e)->entry.target_offset = offsetof(typeof(*(e)), target); \
|
||||
(e)->entry.next_offset = sizeof(*(e)); \
|
||||
(e)->target.target.u.target_size = sizeof(*(e)) - sizeof((e)->entry); \
|
||||
(e)->target.target.u.target_size = sizeof(*(e)) - \
|
||||
(e)->entry.target_offset; \
|
||||
strlcpy((e)->target.target.u.user.name, (target_name), \
|
||||
sizeof((e)->target.target.u.user.name)); \
|
||||
} \
|
||||
@ -269,6 +276,15 @@ struct ipt_get_entries
|
||||
struct ipt_entry entrytable[0];
|
||||
};
|
||||
|
||||
/* ICMP matching stuff */
|
||||
|
||||
struct ipt_icmp
|
||||
{
|
||||
uint8_t type; /* type to match */
|
||||
uint8_t code[2]; /* range of code */
|
||||
uint8_t invflags; /* Inverse flags */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Inline functions
|
||||
****************************************************************************/
|
||||
|
@ -39,9 +39,36 @@
|
||||
|
||||
#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
|
||||
|
||||
/* Values for "inv" field in struct xt_tcp. */
|
||||
|
||||
#define XT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */
|
||||
#define XT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */
|
||||
#define XT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */
|
||||
#define XT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */
|
||||
#define XT_TCP_INV_MASK 0x0F /* All possible flags. */
|
||||
|
||||
/* Values for "invflags" field in struct xt_udp. */
|
||||
|
||||
#define XT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */
|
||||
#define XT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */
|
||||
#define XT_UDP_INV_MASK 0x03 /* All possible flags. */
|
||||
|
||||
/* Target names */
|
||||
|
||||
#define XT_STANDARD_TARGET "" /* Standard return verdict, or do jump. */
|
||||
#define XT_ERROR_TARGET "ERROR"
|
||||
#define XT_MASQUERADE_TARGET "MASQUERADE"
|
||||
#define XT_REJECT_TARGET "REJECT"
|
||||
|
||||
/* Match name to simplify our code */
|
||||
|
||||
#define XT_MATCH_NAME_TCP "tcp"
|
||||
#define XT_MATCH_NAME_UDP "udp"
|
||||
#define XT_MATCH_NAME_ICMP "icmp"
|
||||
|
||||
/* Table name to simplify our code */
|
||||
|
||||
#define XT_TABLE_NAME_FILTER "filter"
|
||||
|
||||
/* For standard target */
|
||||
|
||||
@ -156,4 +183,25 @@ struct xt_entry_match
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
/* TCP matching stuff */
|
||||
|
||||
struct xt_tcp
|
||||
{
|
||||
uint16_t spts[2]; /* Source port range. */
|
||||
uint16_t dpts[2]; /* Destination port range. */
|
||||
uint8_t option; /* TCP Option iff non-zero */
|
||||
uint8_t flg_mask; /* TCP flags mask byte */
|
||||
uint8_t flg_cmp; /* TCP flags compare byte */
|
||||
uint8_t invflags; /* Inverse flags */
|
||||
};
|
||||
|
||||
/* UDP matching stuff */
|
||||
|
||||
struct xt_udp
|
||||
{
|
||||
uint16_t spts[2]; /* Source port range. */
|
||||
uint16_t dpts[2]; /* Destination port range. */
|
||||
uint8_t invflags; /* Inverse flags */
|
||||
};
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_NET_NETFILTER_X_TABLES_H */
|
||||
|
@ -28,5 +28,9 @@ if(CONFIG_NET_IPTABLES)
|
||||
list(APPEND SRCS ipt_nat.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_NET_IPFILTER)
|
||||
list(APPEND SRCS ipt_filter.c)
|
||||
endif()
|
||||
|
||||
target_sources(net PRIVATE ${SRCS})
|
||||
endif()
|
||||
|
@ -8,6 +8,6 @@ config NET_IPTABLES
|
||||
default y
|
||||
depends on NET_IPv4
|
||||
depends on NET_SOCKOPTS
|
||||
depends on NET_NAT # May change dependency if we have firewall later.
|
||||
depends on NET_NAT || NET_IPFILTER
|
||||
---help---
|
||||
Enable or disable iptables compatible interface (for NAT).
|
||||
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_NET_NAT),y)
|
||||
NET_CSRCS += ipt_nat.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_IPFILTER),y)
|
||||
NET_CSRCS += ipt_filter.c
|
||||
endif
|
||||
|
||||
# Include Netfilter build support
|
||||
|
||||
DEPPATH += --dep-path netfilter
|
||||
|
408
net/netfilter/ipt_filter.c
Normal file
408
net/netfilter/ipt_filter.c
Normal file
@ -0,0 +1,408 @@
|
||||
/****************************************************************************
|
||||
* net/netfilter/ipt_filter.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/netfilter/ip_tables.h>
|
||||
#include <nuttx/net/netfilter/x_tables.h>
|
||||
|
||||
#include "ipfilter/ipfilter.h"
|
||||
#include "netdev/netdev.h"
|
||||
#include "netfilter/iptables.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_chain
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables chain to ipfilter chain.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static enum ipfilter_chain_e convert_chain(enum nf_inet_hooks hook)
|
||||
{
|
||||
switch (hook)
|
||||
{
|
||||
case NF_INET_LOCAL_IN:
|
||||
return IPFILTER_CHAIN_INPUT;
|
||||
|
||||
case NF_INET_FORWARD:
|
||||
return IPFILTER_CHAIN_FORWARD;
|
||||
|
||||
case NF_INET_LOCAL_OUT:
|
||||
default:
|
||||
return IPFILTER_CHAIN_OUTPUT;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_invflags
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables invflags to ipfilter invflags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - The ipfilter entry to be filled.
|
||||
* invflags - The iptables invflags to be converted.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void convert_invflags(FAR struct ipfilter_entry_s *entry,
|
||||
uint8_t invflags)
|
||||
{
|
||||
entry->inv_indev = !!(invflags & IPT_INV_VIA_IN);
|
||||
entry->inv_outdev = !!(invflags & IPT_INV_VIA_OUT);
|
||||
entry->inv_proto = !!(invflags & IPT_INV_PROTO);
|
||||
entry->inv_srcip = !!(invflags & IPT_INV_SRCIP);
|
||||
entry->inv_dstip = !!(invflags & IPT_INV_DSTIP);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_tcpudp
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables tcp/udp match to ipfilter entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - The ipfilter entry to be filled.
|
||||
* spts - The source ports to be converted.
|
||||
* dpts - The destination ports to be converted.
|
||||
* invflags - The iptables tcp/udp invflags to be converted.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void convert_tcpudp(FAR struct ipfilter_entry_s *entry,
|
||||
uint16_t spts[2], uint16_t dpts[2],
|
||||
uint8_t invflags)
|
||||
{
|
||||
entry->match.tcpudp.sports[0] = spts[0];
|
||||
entry->match.tcpudp.sports[1] = spts[1];
|
||||
entry->match.tcpudp.dports[0] = dpts[0];
|
||||
entry->match.tcpudp.dports[1] = dpts[1];
|
||||
|
||||
entry->inv_sport = !!(invflags & XT_TCP_INV_SRCPT);
|
||||
entry->inv_dport = !!(invflags & XT_TCP_INV_DSTPT);
|
||||
|
||||
entry->match_tcpudp = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_icmp
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables icmp match to ipfilter entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - The ipfilter entry to be filled.
|
||||
* type - The icmp type to be converted.
|
||||
* invflags - The iptables icmp invflags to be converted.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void convert_icmp(FAR struct ipfilter_entry_s *entry, uint8_t type,
|
||||
uint8_t invflags)
|
||||
{
|
||||
entry->match.icmp.type = type;
|
||||
entry->inv_icmp = !!(invflags & IPT_ICMP_INV);
|
||||
entry->match_icmp = 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_target
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables target to ipfilter target.
|
||||
*
|
||||
* Input Parameters:
|
||||
* target - The iptables target to be converted.
|
||||
*
|
||||
* Returned Value:
|
||||
* The converted ipfilter target.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t convert_target(FAR const struct xt_entry_target *target)
|
||||
{
|
||||
if (strcmp(target->u.user.name, XT_REJECT_TARGET) == 0)
|
||||
{
|
||||
return IPFILTER_TARGET_REJECT;
|
||||
}
|
||||
|
||||
if (strcmp(target->u.user.name, XT_STANDARD_TARGET) == 0)
|
||||
{
|
||||
int verdict = ((FAR const struct xt_standard_target *)target)->verdict;
|
||||
verdict = -verdict - 1;
|
||||
|
||||
if (verdict == NF_ACCEPT)
|
||||
{
|
||||
return IPFILTER_TARGET_ACCEPT;
|
||||
}
|
||||
else if (verdict == NF_DROP)
|
||||
{
|
||||
return IPFILTER_TARGET_DROP;
|
||||
}
|
||||
}
|
||||
|
||||
nwarn("WARNING: Unsupported target %s\n", target->u.user.name);
|
||||
return IPFILTER_TARGET_DROP;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: convert_entry
|
||||
*
|
||||
* Description:
|
||||
* Convert iptables entry to ipfilter entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - The iptables entry to be converted.
|
||||
*
|
||||
* Returned Value:
|
||||
* The converted ipfilter entry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct ipv4_filter_entry_s *
|
||||
convert_entry(FAR const struct ipt_entry *entry)
|
||||
{
|
||||
FAR const struct xt_entry_match *match;
|
||||
FAR const struct xt_entry_target *target;
|
||||
FAR struct ipv4_filter_entry_s *filter =
|
||||
(FAR struct ipv4_filter_entry_s *)ipfilter_cfg_alloc(PF_INET);
|
||||
if (filter == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
match = IPT_MATCH(entry);
|
||||
target = IPT_TARGET(entry);
|
||||
|
||||
/* Convert common fields */
|
||||
|
||||
filter->sip = entry->ip.src.s_addr;
|
||||
filter->dip = entry->ip.dst.s_addr;
|
||||
filter->smsk = entry->ip.smsk.s_addr;
|
||||
filter->dmsk = entry->ip.dmsk.s_addr;
|
||||
|
||||
filter->common.indev = netdev_findbyname(entry->ip.iniface);
|
||||
filter->common.outdev = netdev_findbyname(entry->ip.outiface);
|
||||
filter->common.proto = entry->ip.proto;
|
||||
filter->common.target = convert_target(target);
|
||||
|
||||
convert_invflags(&filter->common, entry->ip.invflags);
|
||||
|
||||
/* Convert match fields */
|
||||
|
||||
if (entry->target_offset < sizeof(struct xt_entry_match))
|
||||
{
|
||||
ninfo("No match inside entry, skip match conversion.\n");
|
||||
goto skip_match;
|
||||
}
|
||||
|
||||
switch (entry->ip.proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0)
|
||||
{
|
||||
FAR struct xt_tcp *tcp = (FAR struct xt_tcp *)(match + 1);
|
||||
convert_tcpudp(&filter->common, tcp->spts, tcp->dpts,
|
||||
tcp->invflags);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0)
|
||||
{
|
||||
FAR struct xt_udp *udp = (FAR struct xt_udp *)(match + 1);
|
||||
convert_tcpudp(&filter->common, udp->spts, udp->dpts,
|
||||
udp->invflags);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPPROTO_ICMP:
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_ICMP) == 0)
|
||||
{
|
||||
FAR struct ipt_icmp *icmp = (FAR struct ipt_icmp *)(match + 1);
|
||||
convert_icmp(&filter->common, icmp->type, icmp->invflags);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
skip_match:
|
||||
return filter;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adjust_filter
|
||||
*
|
||||
* Description:
|
||||
* Adjust filter config according to the iptables config.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config got from user space to control filter table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void adjust_filter(FAR const struct ipt_replace *repl)
|
||||
{
|
||||
FAR const struct ipt_entry *entry;
|
||||
FAR const uint8_t *head;
|
||||
enum ipfilter_chain_e chain;
|
||||
enum nf_inet_hooks hook;
|
||||
size_t size;
|
||||
|
||||
for (hook = NF_INET_LOCAL_IN; hook <= NF_INET_LOCAL_OUT; hook++)
|
||||
{
|
||||
/* Clear all filter config first. */
|
||||
|
||||
chain = convert_chain(hook);
|
||||
ipfilter_cfg_clear(PF_INET, chain);
|
||||
|
||||
/* Set filter config according to iptables config. */
|
||||
|
||||
head = (FAR const uint8_t *)repl->entries + repl->hook_entry[hook];
|
||||
size = repl->underflow[hook] - repl->hook_entry[hook];
|
||||
|
||||
/* We need the underflow entry as the default of the chain. */
|
||||
|
||||
size++;
|
||||
|
||||
ipt_entry_for_every(entry, head, size)
|
||||
{
|
||||
FAR struct ipv4_filter_entry_s *filter = convert_entry(entry);
|
||||
if (filter != NULL)
|
||||
{
|
||||
ipfilter_cfg_add(&filter->common, PF_INET, chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
nwarn("WARNING: Failed to convert entry!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipt_filter_init
|
||||
*
|
||||
* Description:
|
||||
* Init filter table data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct ipt_replace *ipt_filter_init(void)
|
||||
{
|
||||
return ipt_alloc_table(XT_TABLE_NAME_FILTER, FILTER_VALID_HOOKS);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipt_filter_apply
|
||||
*
|
||||
* Description:
|
||||
* Try to apply filter rules, will do nothing if failed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config got from user space to control filter table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ipt_filter_apply(FAR const struct ipt_replace *repl)
|
||||
{
|
||||
FAR const struct ipt_entry *entry;
|
||||
FAR const struct xt_entry_match *match;
|
||||
FAR const struct xt_entry_target *target;
|
||||
|
||||
/* Check config first. */
|
||||
|
||||
ipt_entry_for_every(entry, repl->entries, repl->size)
|
||||
{
|
||||
match = IPT_MATCH(entry);
|
||||
target = IPT_TARGET(entry);
|
||||
|
||||
/* Check match type matches the protocol */
|
||||
|
||||
if (entry->target_offset >= sizeof(struct xt_entry_match))
|
||||
{
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0 &&
|
||||
entry->ip.proto != IPPROTO_TCP)
|
||||
{
|
||||
nwarn("WARNING: TCP match for non-TCP protocol\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_UDP) == 0 &&
|
||||
entry->ip.proto != IPPROTO_UDP)
|
||||
{
|
||||
nwarn("WARNING: UDP match for non-UDP protocol\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (strcmp(match->u.user.name, XT_MATCH_NAME_ICMP) == 0 &&
|
||||
entry->ip.proto != IPPROTO_ICMP)
|
||||
{
|
||||
nwarn("WARNING: ICMP match for non-ICMP protocol\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check target type */
|
||||
|
||||
if (strcmp(target->u.user.name, XT_REJECT_TARGET) != 0 &&
|
||||
strcmp(target->u.user.name, XT_STANDARD_TARGET) != 0 &&
|
||||
strcmp(target->u.user.name, XT_ERROR_TARGET) != 0)
|
||||
{
|
||||
nwarn("WARNING: Unsupported target %s\n", target->u.user.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set config table into ip filter. */
|
||||
|
||||
adjust_filter(repl);
|
||||
|
||||
return OK;
|
||||
}
|
@ -81,6 +81,9 @@ static struct ipt_table_s g_tables[] =
|
||||
#ifdef CONFIG_NET_NAT
|
||||
{NULL, ipt_nat_init, ipt_nat_apply},
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
{NULL, ipt_filter_init, ipt_filter_apply},
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -105,5 +105,32 @@ FAR struct ipt_replace *ipt_nat_init(void);
|
||||
int ipt_nat_apply(FAR const struct ipt_replace *repl);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipt_filter_init
|
||||
*
|
||||
* Description:
|
||||
* Init filter table data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
FAR struct ipt_replace *ipt_filter_init(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipt_filter_apply
|
||||
*
|
||||
* Description:
|
||||
* Try to apply filter rules, will do nothing if failed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config got from user space to control filter table.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
int ipt_filter_apply(FAR const struct ipt_replace *repl);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NET_IPTABLES */
|
||||
#endif /* __NET_NETFILTER_IPTABLES_H */
|
||||
|
Loading…
Reference in New Issue
Block a user