netlib/ip6tables: Add functions for ip6tables & filter table
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
8ae06462eb
commit
3022f836dc
@ -390,8 +390,11 @@ int netlib_obtain_ipv6addr(FAR const char *ifname);
|
||||
|
||||
struct ipt_replace; /* Forward reference */
|
||||
struct ipt_entry; /* Forward reference */
|
||||
struct ip6t_replace; /* Forward reference */
|
||||
struct ip6t_entry; /* Forward reference */
|
||||
enum nf_inet_hooks; /* Forward reference */
|
||||
|
||||
# ifdef CONFIG_NET_IPv4
|
||||
FAR struct ipt_replace *netlib_ipt_prepare(FAR const char *table);
|
||||
int netlib_ipt_commit(FAR const struct ipt_replace *repl);
|
||||
int netlib_ipt_flush(FAR const char *table, enum nf_inet_hooks hook);
|
||||
@ -409,15 +412,40 @@ int netlib_ipt_delete(FAR struct ipt_replace *repl,
|
||||
int netlib_ipt_fillifname(FAR struct ipt_entry *entry,
|
||||
FAR const char *inifname,
|
||||
FAR const char *outifname);
|
||||
# ifdef CONFIG_NET_NAT
|
||||
# ifdef CONFIG_NET_NAT
|
||||
FAR struct ipt_entry *netlib_ipt_masquerade_entry(FAR const char *ifname);
|
||||
# endif
|
||||
# ifdef CONFIG_NET_IPFILTER
|
||||
# endif
|
||||
# ifdef CONFIG_NET_IPFILTER
|
||||
FAR struct ipt_entry *netlib_ipt_filter_entry(FAR const char *target,
|
||||
int verdict,
|
||||
uint8_t match_proto);
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
# endif /* CONFIG_NET_IPv4 */
|
||||
# ifdef CONFIG_NET_IPv6
|
||||
FAR struct ip6t_replace *netlib_ip6t_prepare(FAR const char *table);
|
||||
int netlib_ip6t_commit(FAR const struct ip6t_replace *repl);
|
||||
int netlib_ip6t_flush(FAR const char *table, enum nf_inet_hooks hook);
|
||||
int netlib_ip6t_policy(FAR const char *table, enum nf_inet_hooks hook,
|
||||
int verdict);
|
||||
int netlib_ip6t_append(FAR struct ip6t_replace **repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook);
|
||||
int netlib_ip6t_insert(FAR struct ip6t_replace **repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook, int rulenum);
|
||||
int netlib_ip6t_delete(FAR struct ip6t_replace *repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook, int rulenum);
|
||||
int netlib_ip6t_fillifname(FAR struct ip6t_entry *entry,
|
||||
FAR const char *inifname,
|
||||
FAR const char *outifname);
|
||||
# ifdef CONFIG_NET_IPFILTER
|
||||
FAR struct ip6t_entry *netlib_ip6t_filter_entry(FAR const char *target,
|
||||
int verdict,
|
||||
uint8_t match_proto);
|
||||
# endif
|
||||
# endif /* CONFIG_NET_IPv6 */
|
||||
#endif /* CONFIG_NET_IPTABLES */
|
||||
|
||||
#ifdef CONFIG_NETLINK_NETFILTER
|
||||
/* Netfilter connection tracking support */
|
||||
|
@ -73,6 +73,9 @@ if(CONFIG_NETUTILS_NETLIB)
|
||||
if(CONFIG_NETLINK_ROUTE)
|
||||
list(APPEND SRCS netlib_getnbtab.c)
|
||||
endif()
|
||||
if(CONFIG_NET_IPTABLES)
|
||||
list(APPEND SRCS netlib_ip6tables.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Device support
|
||||
|
@ -74,6 +74,9 @@ endif
|
||||
ifeq ($(CONFIG_NETLINK_ROUTE),y)
|
||||
CSRCS += netlib_getnbtab.c
|
||||
endif
|
||||
ifeq ($(CONFIG_NET_IPTABLES),y)
|
||||
CSRCS += netlib_ip6tables.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# Device support
|
||||
|
753
netutils/netlib/netlib_ip6tables.c
Normal file
753
netutils/netlib/netlib_ip6tables.c
Normal file
@ -0,0 +1,753 @@
|
||||
/****************************************************************************
|
||||
* apps/netutils/netlib/netlib_ip6tables.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 <sys/socket.h>
|
||||
|
||||
#include <nuttx/net/netfilter/ip6_tables.h>
|
||||
|
||||
#include "netutils/netlib.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define IP6T_FILL_MATCH(e, match_name) \
|
||||
do \
|
||||
{ \
|
||||
strlcpy((e)->match.u.user.name, (match_name), \
|
||||
sizeof((e)->match.u.user.name)); \
|
||||
(e)->match.u.match_size = offsetof(typeof(*(e)), target) - \
|
||||
offsetof(typeof(*(e)), match); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct ip6t_filter_entry_s
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
|
||||
/* Compatible with ACCEPT/DROP/REJECT target. */
|
||||
|
||||
struct xt_standard_target target;
|
||||
};
|
||||
|
||||
struct ip6t_filter_tcp_entry_s
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct xt_entry_match match;
|
||||
struct xt_tcp tcp;
|
||||
struct xt_standard_target target;
|
||||
};
|
||||
|
||||
struct ip6t_filter_udp_entry_s
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct xt_entry_match match;
|
||||
struct xt_udp udp;
|
||||
struct xt_standard_target target;
|
||||
};
|
||||
|
||||
struct ip6t_filter_icmp_entry_s
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct xt_entry_match match;
|
||||
struct ip6t_icmp icmp;
|
||||
struct xt_standard_target target;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_entry_by_rulenum
|
||||
*
|
||||
* Description:
|
||||
* Get entry in repl at rulenum (1 = first) in hook.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* hook - The hook of the entry.
|
||||
* rulenum - The place to get.
|
||||
* allow_last - Whether allow to get last entry (at underflow), may insert
|
||||
* entry just before last entry, but don't delete last entry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct ip6t_entry *
|
||||
netlib_ip6t_entry_by_rulenum(FAR struct ip6t_replace *repl,
|
||||
enum nf_inet_hooks hook, int rulenum,
|
||||
bool allow_last)
|
||||
{
|
||||
FAR struct ip6t_entry *e;
|
||||
FAR uint8_t *head = (FAR uint8_t *)repl->entries + repl->hook_entry[hook];
|
||||
int size = repl->underflow[hook] - repl->hook_entry[hook];
|
||||
|
||||
ip6t_entry_for_every(e, head, size)
|
||||
{
|
||||
if (--rulenum <= 0)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return (allow_last && rulenum == 1) ? e : NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_insert_internal
|
||||
*
|
||||
* Description:
|
||||
* Insert an entry into config at insert_point.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* entry - The entry to insert.
|
||||
* hook - The hook of the entry.
|
||||
* insert_point - The offset to put the entry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int netlib_ip6t_insert_internal(FAR struct ip6t_replace **replace,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook,
|
||||
unsigned int insert_point)
|
||||
{
|
||||
FAR struct ip6t_replace *repl = *replace;
|
||||
FAR uint8_t *base;
|
||||
size_t new_size;
|
||||
|
||||
new_size = sizeof(*repl) + repl->size + entry->next_offset;
|
||||
repl = realloc(repl, new_size);
|
||||
if (repl == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Insert new entry into entry table. */
|
||||
|
||||
base = (FAR uint8_t *)repl->entries;
|
||||
memmove(base + insert_point + entry->next_offset, base + insert_point,
|
||||
repl->size - insert_point);
|
||||
memcpy(base + insert_point, entry, entry->next_offset);
|
||||
|
||||
/* Adjust metadata. */
|
||||
|
||||
repl->num_entries++;
|
||||
repl->size += entry->next_offset;
|
||||
|
||||
/* Adjust hook_entry and underflow. */
|
||||
|
||||
repl->underflow[hook++] += entry->next_offset;
|
||||
for (; hook < NF_INET_NUMHOOKS; hook++)
|
||||
{
|
||||
if (repl->valid_hooks & (1 << hook))
|
||||
{
|
||||
repl->hook_entry[hook] += entry->next_offset;
|
||||
repl->underflow[hook] += entry->next_offset;
|
||||
}
|
||||
}
|
||||
|
||||
*replace = repl;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_delete_internal
|
||||
*
|
||||
* Description:
|
||||
* Delete an entry from config.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* entry - The entry to remove, should be in repl.
|
||||
* hook - The hook of the entry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void netlib_ip6t_delete_internal(FAR struct ip6t_replace *repl,
|
||||
FAR struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook)
|
||||
{
|
||||
unsigned int delete_len = entry->next_offset;
|
||||
|
||||
/* Adjust metadata. */
|
||||
|
||||
repl->num_entries--;
|
||||
repl->size -= delete_len;
|
||||
|
||||
/* Remove entry from entry table. */
|
||||
|
||||
memmove((FAR uint8_t *)entry, (FAR uint8_t *)entry + delete_len,
|
||||
repl->size - ((uintptr_t)entry - (uintptr_t)repl->entries));
|
||||
|
||||
/* Adjust hook_entry and underflow. */
|
||||
|
||||
repl->underflow[hook++] -= delete_len;
|
||||
for (; hook < NF_INET_NUMHOOKS; hook++)
|
||||
{
|
||||
if (repl->valid_hooks & (1 << hook))
|
||||
{
|
||||
repl->hook_entry[hook] -= delete_len;
|
||||
repl->underflow[hook] -= delete_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_prepare
|
||||
*
|
||||
* Description:
|
||||
* Read current config from kernel space.
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - The table name to read from.
|
||||
*
|
||||
* Returned Value:
|
||||
* The pointer to the config, or NULL if failed.
|
||||
* Caller must free it after use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct ip6t_replace *netlib_ip6t_prepare(FAR const char *table)
|
||||
{
|
||||
struct ip6t_getinfo info;
|
||||
FAR struct ip6t_get_entries *entries;
|
||||
FAR struct ip6t_replace *repl = NULL;
|
||||
socklen_t len;
|
||||
int sockfd;
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
|
||||
if (sockfd < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to create socket %d!\n", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strlcpy(info.name, table, sizeof(info.name));
|
||||
len = sizeof(info);
|
||||
|
||||
if (getsockopt(sockfd, IPPROTO_IPV6, IP6T_SO_GET_INFO, &info, &len) < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to get info for table %s %d!\n", table, errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
len = sizeof(*entries) + info.size;
|
||||
entries = malloc(len);
|
||||
if (entries == NULL)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
|
||||
strlcpy(entries->name, table, sizeof(entries->name));
|
||||
entries->size = info.size;
|
||||
if (getsockopt(sockfd, IPPROTO_IPV6, IP6T_SO_GET_ENTRIES, entries, &len)
|
||||
< 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to get entries for table %s %d!\n",
|
||||
table, errno);
|
||||
goto errout_with_entries;
|
||||
}
|
||||
|
||||
repl = malloc(sizeof(*repl) + info.size);
|
||||
if (repl == NULL)
|
||||
{
|
||||
goto errout_with_entries;
|
||||
}
|
||||
|
||||
strlcpy(repl->name, table, sizeof(repl->name));
|
||||
|
||||
repl->valid_hooks = info.valid_hooks;
|
||||
repl->num_entries = info.num_entries;
|
||||
repl->size = info.size;
|
||||
repl->num_counters = 0;
|
||||
repl->counters = NULL;
|
||||
|
||||
memcpy(repl->hook_entry, info.hook_entry, sizeof(repl->hook_entry));
|
||||
memcpy(repl->underflow, info.underflow, sizeof(repl->underflow));
|
||||
memcpy(repl->entries, entries->entrytable, info.size);
|
||||
|
||||
errout_with_entries:
|
||||
free(entries);
|
||||
|
||||
errout:
|
||||
close(sockfd);
|
||||
return repl;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_commit
|
||||
*
|
||||
* Description:
|
||||
* Set config into kernel space.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config to commit.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_commit(FAR const struct ip6t_replace *repl)
|
||||
{
|
||||
int ret;
|
||||
int sockfd;
|
||||
|
||||
if (repl == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
|
||||
if (sockfd < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to create socket %d!\n", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = setsockopt(sockfd, IPPROTO_IPV6, IP6T_SO_SET_REPLACE, repl,
|
||||
sizeof(*repl) + repl->size);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -errno;
|
||||
fprintf(stderr, "Failed to commit %d!\n", ret);
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_flush
|
||||
*
|
||||
* Description:
|
||||
* Flush all config in the table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - The table name to flush.
|
||||
* hook - The hook to flush, NF_INET_NUMHOOKS for all.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_flush(FAR const char *table, enum nf_inet_hooks hook)
|
||||
{
|
||||
FAR struct ip6t_replace *repl = netlib_ip6t_prepare(table);
|
||||
unsigned int cur_hook;
|
||||
int ret;
|
||||
|
||||
if (repl == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to read table %s from kernel!\n", table);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (hook != NF_INET_NUMHOOKS && (repl->valid_hooks & (1 << hook)) == 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid hook number %d for table %s!\n", hook, table);
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (cur_hook = 0; cur_hook < NF_INET_NUMHOOKS; cur_hook++)
|
||||
{
|
||||
if ((repl->valid_hooks & (1 << cur_hook)) != 0 &&
|
||||
(hook == NF_INET_NUMHOOKS || hook == cur_hook))
|
||||
{
|
||||
/* Remove all user entries in current hook. */
|
||||
|
||||
while (repl->underflow[cur_hook] > repl->hook_entry[cur_hook])
|
||||
{
|
||||
ret = netlib_ip6t_delete(repl, NULL, cur_hook, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = netlib_ip6t_commit(repl);
|
||||
|
||||
errout:
|
||||
free(repl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_policy
|
||||
*
|
||||
* Description:
|
||||
* Set policy for the table. It's a common operation, but may only take
|
||||
* effect on filter-related tables.
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - The table name to set policy.
|
||||
* hook - The hook to set policy.
|
||||
* verdict - The verdict to set.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_policy(FAR const char *table, enum nf_inet_hooks hook,
|
||||
int verdict)
|
||||
{
|
||||
FAR struct ip6t_replace *repl = netlib_ip6t_prepare(table);
|
||||
FAR struct ip6t_entry *entry;
|
||||
FAR struct xt_standard_target *target;
|
||||
int ret;
|
||||
|
||||
if (repl == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to read table %s from kernel!\n", table);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if ((repl->valid_hooks & (1 << hook)) == 0)
|
||||
{
|
||||
fprintf(stderr, "Invalid hook number %d for table %s!\n", hook, table);
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* The underflow entry is the default policy of the chain. */
|
||||
|
||||
entry = (FAR struct ip6t_entry *)((uintptr_t)repl->entries +
|
||||
repl->underflow[hook]);
|
||||
target = (FAR struct xt_standard_target *)IP6T_TARGET(entry);
|
||||
if (strcmp(target->target.u.user.name, XT_STANDARD_TARGET) != 0)
|
||||
{
|
||||
fprintf(stderr, "Wrong target %s!\n", target->target.u.user.name);
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
target->verdict = verdict;
|
||||
|
||||
ret = netlib_ip6t_commit(repl);
|
||||
|
||||
errout:
|
||||
free(repl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_append
|
||||
*
|
||||
* Description:
|
||||
* Append an entry into config, will be put to as last config of the chain
|
||||
* corresponding to hook.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* entry - The entry to append.
|
||||
* hook - The hook of the entry.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_append(FAR struct ip6t_replace **repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook)
|
||||
{
|
||||
if (repl == NULL || *repl == NULL || entry == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((*repl)->valid_hooks & (1 << hook)) == 0)
|
||||
{
|
||||
fprintf(stderr, "Not valid hook %d for this table!\n", hook);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return netlib_ip6t_insert_internal(repl, entry, hook,
|
||||
(*repl)->underflow[hook]);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_insert
|
||||
*
|
||||
* Description:
|
||||
* Insert an entry into config, will be put to as first config of the chain
|
||||
* corresponding to hook.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* entry - The entry to insert.
|
||||
* hook - The hook of the entry.
|
||||
* rulenum - The place to insert, 1 = first.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_insert(FAR struct ip6t_replace **repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook, int rulenum)
|
||||
{
|
||||
FAR struct ip6t_entry *e;
|
||||
|
||||
if (repl == NULL || *repl == NULL || entry == NULL || rulenum <= 0)
|
||||
{
|
||||
fprintf(stderr, "Not valid param %p, %p, rulenum %d!\n",
|
||||
repl, entry, rulenum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((*repl)->valid_hooks & (1 << hook)) == 0)
|
||||
{
|
||||
fprintf(stderr, "Not valid hook %d for this table!\n", hook);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
e = netlib_ip6t_entry_by_rulenum(*repl, hook, rulenum, true);
|
||||
if (e == NULL)
|
||||
{
|
||||
fprintf(stderr, "Rulenum %d too big!\n", rulenum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return netlib_ip6t_insert_internal(repl, entry, hook,
|
||||
(uintptr_t)e - (uintptr_t)(*repl)->entries);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_delete
|
||||
*
|
||||
* Description:
|
||||
* Delete an entry from config.
|
||||
*
|
||||
* Input Parameters:
|
||||
* repl - The config (to set into kernel later).
|
||||
* entry - The entry to delete, choose either entry or rulenum.
|
||||
* hook - The hook of the entry.
|
||||
* rulenum - The place to delete, 1 = first, set entry to NULL to use this.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_delete(FAR struct ip6t_replace *repl,
|
||||
FAR const struct ip6t_entry *entry,
|
||||
enum nf_inet_hooks hook, int rulenum)
|
||||
{
|
||||
FAR struct ip6t_entry *e;
|
||||
FAR uint8_t *head;
|
||||
int size;
|
||||
|
||||
if (repl == NULL || (entry == NULL && rulenum <= 0))
|
||||
{
|
||||
fprintf(stderr, "Not valid param %p, %p, rulenum %d!\n",
|
||||
repl, entry, rulenum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((repl->valid_hooks & (1 << hook)) == 0)
|
||||
{
|
||||
fprintf(stderr, "Not valid hook %d for this table!\n", hook);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry == NULL) /* Use rulenum instead. */
|
||||
{
|
||||
e = netlib_ip6t_entry_by_rulenum(repl, hook, rulenum, false);
|
||||
if (e == NULL)
|
||||
{
|
||||
fprintf(stderr, "Rulenum %d too big!\n", rulenum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
netlib_ip6t_delete_internal(repl, e, hook);
|
||||
return OK;
|
||||
}
|
||||
|
||||
head = (FAR uint8_t *)repl->entries + repl->hook_entry[hook];
|
||||
size = repl->underflow[hook] - repl->hook_entry[hook];
|
||||
ip6t_entry_for_every(e, head, size)
|
||||
{
|
||||
if (e->next_offset == entry->next_offset &&
|
||||
e->target_offset == entry->target_offset &&
|
||||
memcmp(&e->ipv6, &entry->ipv6, sizeof(struct ip6t_ip6)) == 0 &&
|
||||
memcmp(&e->elems, &entry->elems,
|
||||
e->next_offset - offsetof(struct ip6t_entry, elems)) == 0)
|
||||
{
|
||||
netlib_ip6t_delete_internal(repl, e, hook);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_fillifname
|
||||
*
|
||||
* Description:
|
||||
* Fill inifname and outifname into entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* entry - The entry to fill.
|
||||
* inifname - The input device name, NULL for no change.
|
||||
* outifname - The output device name, NULL for no change.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int netlib_ip6t_fillifname(FAR struct ip6t_entry *entry,
|
||||
FAR const char *inifname,
|
||||
FAR const char *outifname)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (inifname != NULL)
|
||||
{
|
||||
len = strlen(inifname);
|
||||
if (len + 1 > IFNAMSIZ)
|
||||
{
|
||||
fprintf(stderr, "Too long inifname %s!\n", inifname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strlcpy(entry->ipv6.iniface, inifname, sizeof(entry->ipv6.iniface));
|
||||
memset(entry->ipv6.iniface_mask, 0xff, len + 1);
|
||||
}
|
||||
|
||||
if (outifname != NULL)
|
||||
{
|
||||
len = strlen(outifname);
|
||||
if (len + 1 > IFNAMSIZ)
|
||||
{
|
||||
fprintf(stderr, "Too long outifname %s!\n", outifname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strlcpy(entry->ipv6.outiface, outifname, sizeof(entry->ipv6.outiface));
|
||||
memset(entry->ipv6.outiface_mask, 0xff, len + 1);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlib_ip6t_filter_entry
|
||||
*
|
||||
* Description:
|
||||
* Alloc an entry with filter target.
|
||||
*
|
||||
* Input Parameters:
|
||||
* target - The target name to apply.
|
||||
* verdict - The verdict to set, compatible with reject target's code
|
||||
* match_proto - The protocol match type in the entry, 0 for no match.
|
||||
*
|
||||
* Returned Value:
|
||||
* The pointer to the entry, or NULL if failed.
|
||||
* Caller must free it after use.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
FAR struct ip6t_entry *netlib_ip6t_filter_entry(FAR const char *target,
|
||||
int verdict,
|
||||
uint8_t match_proto)
|
||||
{
|
||||
if (target == NULL)
|
||||
{
|
||||
fprintf(stderr, "Empty target!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (match_proto)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
FAR struct ip6t_filter_entry_s *entry = zalloc(sizeof(*entry));
|
||||
if (entry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IP6T_FILL_ENTRY(entry, target);
|
||||
entry->target.verdict = verdict;
|
||||
return &entry->entry;
|
||||
}
|
||||
|
||||
case IPPROTO_TCP:
|
||||
{
|
||||
FAR struct ip6t_filter_tcp_entry_s *entry = zalloc(sizeof(*entry));
|
||||
if (entry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IP6T_FILL_ENTRY(entry, target);
|
||||
IP6T_FILL_MATCH(entry, XT_MATCH_NAME_TCP);
|
||||
entry->target.verdict = verdict;
|
||||
return &entry->entry;
|
||||
}
|
||||
|
||||
case IPPROTO_UDP:
|
||||
{
|
||||
FAR struct ip6t_filter_udp_entry_s *entry = zalloc(sizeof(*entry));
|
||||
if (entry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IP6T_FILL_ENTRY(entry, target);
|
||||
IP6T_FILL_MATCH(entry, XT_MATCH_NAME_UDP);
|
||||
entry->target.verdict = verdict;
|
||||
return &entry->entry;
|
||||
}
|
||||
|
||||
case IPPROTO_ICMP6:
|
||||
{
|
||||
FAR struct ip6t_filter_icmp_entry_s *entry =
|
||||
zalloc(sizeof(*entry));
|
||||
if (entry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IP6T_FILL_ENTRY(entry, target);
|
||||
IP6T_FILL_MATCH(entry, XT_MATCH_NAME_ICMP6);
|
||||
entry->target.verdict = verdict;
|
||||
return &entry->entry;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user