f7181676b7
Add a firewall compatible with Linux's iptables and ip6tables, with chains at similar points in the packet processing path. NIC ─> ipv[46]_input ┬> ipv[46]_forward ─> [FORWARD] ┬> devif_poll_out ─> NIC │ │ │ ┌> tcp ┐ │ │ ├> udp ┤ │ └> [INPUT] ┼> icmp ┼> [OUTPUT] ┘ ├> icmp6 ┤ └> ... ┘ Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
267 lines
8.4 KiB
C
267 lines
8.4 KiB
C
/****************************************************************************
|
|
* net/ipfilter/ipfilter.h
|
|
*
|
|
* 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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __NET_IPFILTER_IPFILTER_H
|
|
#define __NET_IPFILTER_IPFILTER_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <nuttx/compiler.h>
|
|
#include <nuttx/net/ip.h>
|
|
|
|
#ifdef CONFIG_NET_IPFILTER
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#define IPFILTER_TARGET_ACCEPT (0)
|
|
#define IPFILTER_TARGET_DROP (-1)
|
|
#define IPFILTER_TARGET_REJECT (-2)
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
enum ipfilter_chain_e
|
|
{
|
|
IPFILTER_CHAIN_INPUT = 0, /* = NF_IP_LOCAL_IN - 1, Input chain */
|
|
IPFILTER_CHAIN_FORWARD = 1, /* = NF_IP_FORWARD - 1, Forward chain */
|
|
IPFILTER_CHAIN_OUTPUT = 2, /* = NF_IP_LOCAL_OUT - 1, Output chain */
|
|
IPFILTER_CHAIN_MAX
|
|
};
|
|
|
|
/* The filter configuration entry */
|
|
|
|
struct ipfilter_entry_s
|
|
{
|
|
FAR struct ipfilter_entry_s *flink;
|
|
|
|
FAR struct net_driver_s *indev;
|
|
FAR struct net_driver_s *outdev;
|
|
|
|
union /* Matches in host byte order (because it's range) */
|
|
{
|
|
struct
|
|
{
|
|
uint16_t sports[2]; /* Source port range */
|
|
uint16_t dports[2]; /* Destination port range */
|
|
} tcpudp;
|
|
|
|
struct
|
|
{
|
|
uint8_t type; /* Type to match, 0xFF = ALL (Same as Linux) */
|
|
} icmp;
|
|
} match;
|
|
|
|
uint8_t proto; /* Protocol to match, 0 = ALL (Same as Linux) */
|
|
int8_t target;
|
|
|
|
/* Match flags, whether we need to match protocol in detail */
|
|
|
|
uint8_t match_tcpudp : 1; /* Match TCP/UDP */
|
|
uint8_t match_icmp : 1; /* Match ICMP */
|
|
|
|
/* Inverse flags */
|
|
|
|
uint8_t inv_indev : 1; /* Inverse input device */
|
|
uint8_t inv_outdev : 1; /* Inverse output device */
|
|
uint8_t inv_proto : 1; /* Inverse protocol */
|
|
uint8_t inv_srcip : 1; /* Inverse source IP */
|
|
uint8_t inv_dstip : 1; /* Inverse destination IP */
|
|
uint8_t inv_sport : 1; /* Inverse source port */
|
|
uint8_t inv_dport : 1; /* Inverse destination port */
|
|
uint8_t inv_icmp : 1; /* Inverse ICMP type */
|
|
};
|
|
|
|
struct ipv4_filter_entry_s
|
|
{
|
|
struct ipfilter_entry_s common;
|
|
|
|
/* Addresses in network byte order */
|
|
|
|
in_addr_t sip;
|
|
in_addr_t dip;
|
|
in_addr_t smsk;
|
|
in_addr_t dmsk;
|
|
};
|
|
|
|
struct ipv6_filter_entry_s
|
|
{
|
|
struct ipfilter_entry_s common;
|
|
|
|
/* Addresses in network byte order */
|
|
|
|
net_ipv6addr_t sip;
|
|
net_ipv6addr_t dip;
|
|
net_ipv6addr_t smsk;
|
|
net_ipv6addr_t dmsk;
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Public Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: ipfilter_cfg_alloc
|
|
*
|
|
* Description:
|
|
* Allocate a new filter configuration entry for the given address family.
|
|
*
|
|
* Input Parameters:
|
|
* family - The address family of the filter entry
|
|
*
|
|
* Returned Value:
|
|
* A pointer to the newly allocated filter entry. NULL is returned on
|
|
* failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR struct ipfilter_entry_s *ipfilter_cfg_alloc(sa_family_t family);
|
|
|
|
/****************************************************************************
|
|
* Name: ipfilter_cfg_add
|
|
*
|
|
* Description:
|
|
* Add a new filter configuration entry for the given address family to the
|
|
* end of specified chain.
|
|
*
|
|
* Input Parameters:
|
|
* entry - The filter entry to add
|
|
* family - The address family of the filter entry
|
|
* chain - The chain to add the filter entry to
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
void ipfilter_cfg_add(FAR struct ipfilter_entry_s *entry,
|
|
sa_family_t family, enum ipfilter_chain_e chain);
|
|
|
|
/****************************************************************************
|
|
* Name: ipfilter_cfg_clear
|
|
*
|
|
* Description:
|
|
* Clear all filter configuration entries for the given address family from
|
|
* the specified chain.
|
|
*
|
|
* Input Parameters:
|
|
* family - The address family of the filter entry to clear
|
|
* chain - The chain to clear the filter entries from
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
void ipfilter_cfg_clear(sa_family_t family, enum ipfilter_chain_e chain);
|
|
|
|
/****************************************************************************
|
|
* Name: ipv4_filter_in / ipv6_filter_in
|
|
*
|
|
* Description:
|
|
* Handling IPv4/IPv6 filter on local input. Do nothing if the input
|
|
* packet is accepted, set d_len to 0 if the input packet needs to be
|
|
* dropped, and set d_iob to reject reply if the input packet is rejected.
|
|
*
|
|
* Input Parameters:
|
|
* dev - The network device that the packet comes from
|
|
*
|
|
* Returned Value:
|
|
* IPFILTER_TARGET_ACCEPT(0) - The input packet is accepted
|
|
* IPFILTER_TARGET_DROP(-1) - The input packet needs to be dropped
|
|
* IPFILTER_TARGET_REJECT(-2) - The input packet is rejected
|
|
*
|
|
* Assumptions:
|
|
* The network is locked. The d_iob and d_len in the dev are set.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_NET_IPv4
|
|
int ipv4_filter_in(FAR struct net_driver_s *dev);
|
|
#endif
|
|
#ifdef CONFIG_NET_IPv6
|
|
int ipv6_filter_in(FAR struct net_driver_s *dev);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: ipfilter_out
|
|
*
|
|
* Description:
|
|
* Handling filter on local output. Do nothing if the output packet
|
|
* is accepted, set d_len to 0 if the output packet needs to be dropped,
|
|
* and set d_iob to reject reply if the output packet is rejected.
|
|
*
|
|
* Input Parameters:
|
|
* dev - The network device that the packet goes to
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
* Assumptions:
|
|
* The network is locked. Only IPv4 and IPv6 packets call this function.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void ipfilter_out(FAR struct net_driver_s *dev);
|
|
|
|
/****************************************************************************
|
|
* Name: ipv4_filter_fwd / ipv6_filter_fwd
|
|
*
|
|
* Description:
|
|
* Handling IPv4/IPv6 filter on forwarding. Just return the target action,
|
|
* and relies on the caller to do the actual drop / reject.
|
|
*
|
|
* Input Parameters:
|
|
* indev - The network device that the packet comes from
|
|
* outdev - The network device that the packet goes to
|
|
* ipv4/ipv6 - The IPv4/IPv6 header
|
|
*
|
|
* Returned Value:
|
|
* IPFILTER_TARGET_ACCEPT(0) - The input packet is accepted
|
|
* IPFILTER_TARGET_DROP(-1) - The input packet needs to be dropped
|
|
* IPFILTER_TARGET_REJECT(-2) - The input packet needs to be rejected
|
|
*
|
|
* Assumptions:
|
|
* The network is locked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv4)
|
|
int ipv4_filter_fwd(FAR struct net_driver_s *indev,
|
|
FAR struct net_driver_s *outdev,
|
|
FAR struct ipv4_hdr_s *ipv4);
|
|
#endif
|
|
#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv6)
|
|
int ipv6_filter_fwd(FAR struct net_driver_s *indev,
|
|
FAR struct net_driver_s *outdev,
|
|
FAR struct ipv6_hdr_s *ipv6);
|
|
#endif
|
|
|
|
#endif /* CONFIG_NET_IPFILTER */
|
|
#endif /* __NET_IPFILTER_IPFILTER_H */
|