Skip to content

Commit

Permalink
Add tool: ipfw.
Browse files Browse the repository at this point in the history
ipfw -- interface for firewall, packet scheduler, NAT and so on.

It is comprised of several components: the kernel firewall filter rule processor and its integrated packet accounting facility, the logging facility, NAT, a forward facility, a bridge facility, and an ipstealth facility.
Note that the `dummynet` traffic shaper is not merged.
  • Loading branch information
whl739 committed Nov 14, 2017
1 parent 0b8e61a commit b37139c
Show file tree
Hide file tree
Showing 33 changed files with 18,532 additions and 31 deletions.
26 changes: 25 additions & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ X86_INCLUDES=0

HOST_OS:=$(shell uname -s)
#DEBUG=-O0 -gdwarf-2 -g3
#FF_NETGRAPH=1
#FF_IPFW=1

ifeq ($(FF_DPDK),)
FF_DPDK=${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc
Expand Down Expand Up @@ -50,6 +52,10 @@ ifdef FF_NETGRAPH
HOST_CFLAGS+= -DFF_NETGRAPH
endif

ifdef FF_IPFW
HOST_CFLAGS+= -DFF_IPFW
endif

HOST_C= ${CC} -c $(HOST_CFLAGS) ${HOST_INCLUDES} ${WERROR} ${PROF} $<


Expand Down Expand Up @@ -122,6 +128,9 @@ VPATH+= $S/netinet
VPATH+= $S/netinet/libalias
VPATH+= $S/netinet/cc
VPATH+= $S/netipsec
ifdef FF_IPFW
VPATH+= $S/netpfil/ipfw
endif
VPATH+= $S/opencrypto
VPATH+= $S/vm
VPATH+= $S/libkern
Expand Down Expand Up @@ -373,6 +382,21 @@ NETINET_SRCS+= \
alias_sctp.c \
alias_util.c

ifdef FF_IPFW
NETIPFW_SRCS+= \
ip_fw_dynamic.c \
ip_fw_eaction.c \
ip_fw_iface.c \
ip_fw_log.c \
ip_fw_nat.c \
ip_fw_pfil.c \
ip_fw_sockopt.c \
ip_fw_table.c \
ip_fw_table_algo.c \
ip_fw_table_value.c \
ip_fw2.c
endif

ifdef FF_IPSEC
NETINET_SRCS+= \
ip_ipsec.c
Expand Down Expand Up @@ -431,7 +455,7 @@ ASM_SRCS = ${CRYPTO_ASM_SRCS}

SRCS= ${FF_SRCS} ${CRYPTO_SRCS} ${KERN_SRCS} ${LIBKERN_SRCS} ${MACHINE_SRCS}
SRCS+= ${MSRCS} ${NET_SRCS} ${NETGRAPH_SRCS} ${NETINET_SRCS} ${NETINET6_SRCS}
SRCS+= ${NETIPSEC_SRCS} ${OPENCRYPTO_SRCS} ${VM_SRCS}
SRCS+= ${NETIPSEC_SRCS} ${NETIPFW_SRCS} ${OPENCRYPTO_SRCS} ${VM_SRCS}

# If witness is enabled.
# SRCS+= ${KERN_WITNESS_SRCS}
Expand Down
9 changes: 6 additions & 3 deletions lib/ff_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,11 @@ int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag,
* Implemented by user.
*
* @param data
* The data pointer of the packet.
* The data pointer of this packet.
* @param len
* The length of the packet.
* The length of this packet.
* @param queue_id
* Current queue of this packet.
* @param nb_queues
* Number of queues to be dispatched.
*
Expand All @@ -160,7 +162,8 @@ int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag,
* Error occurs or packet is handled by user, packet will be freed.
*
*/
typedef int (*dispatch_func_t)(void *data, uint16_t len, uint16_t nb_queues);
typedef int (*dispatch_func_t)(void *data, uint16_t len,
uint16_t queue_id, uint16_t nb_queues);

/* regist a packet dispath function */
void ff_regist_packet_dispatcher(dispatch_func_t func);
Expand Down
80 changes: 57 additions & 23 deletions lib/ff_dpdk_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
uint16_t len = rte_pktmbuf_data_len(rtem);

if (!pkts_from_ring && packet_dispatcher) {
int ret = (*packet_dispatcher)(data, len, nb_queues);
int ret = (*packet_dispatcher)(data, len, queue_id, nb_queues);
if (ret < 0 || ret >= nb_queues) {
rte_pktmbuf_free(rtem);
continue;
Expand Down Expand Up @@ -994,7 +994,7 @@ process_dispatch_ring(uint8_t port_id, uint16_t queue_id,
}

static inline void
handle_sysctl_msg(struct ff_msg *msg, uint16_t proc_id)
handle_sysctl_msg(struct ff_msg *msg)
{
int ret = ff_sysctl(msg->sysctl.name, msg->sysctl.namelen,
msg->sysctl.old, msg->sysctl.oldlenp, msg->sysctl.new,
Expand All @@ -1005,12 +1005,10 @@ handle_sysctl_msg(struct ff_msg *msg, uint16_t proc_id)
} else {
msg->result = 0;
}

rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

static inline void
handle_ioctl_msg(struct ff_msg *msg, uint16_t proc_id)
handle_ioctl_msg(struct ff_msg *msg)
{
int fd, ret;
fd = ff_socket(AF_INET, SOCK_DGRAM, 0);
Expand All @@ -1029,12 +1027,10 @@ handle_ioctl_msg(struct ff_msg *msg, uint16_t proc_id)
} else {
msg->result = 0;
}

rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

static inline void
handle_route_msg(struct ff_msg *msg, uint16_t proc_id)
handle_route_msg(struct ff_msg *msg)
{
int ret = ff_rtioctl(msg->route.fib, msg->route.data,
&msg->route.len, msg->route.maxlen);
Expand All @@ -1043,23 +1039,19 @@ handle_route_msg(struct ff_msg *msg, uint16_t proc_id)
} else {
msg->result = 0;
}

rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

static struct ff_top_args ff_status;
static inline void
handle_top_msg(struct ff_msg *msg, uint16_t proc_id)
handle_top_msg(struct ff_msg *msg)
{
msg->top = ff_status;
msg->result = 0;

rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

#ifdef FF_NETGRAPH
static inline void
handle_ngctl_msg(struct ff_msg *msg, uint16_t proc_id)
handle_ngctl_msg(struct ff_msg *msg)
{
int ret = ff_ngctl(msg->ngctl.cmd, msg->ngctl.data);
if (ret < 0) {
Expand All @@ -1068,43 +1060,85 @@ handle_ngctl_msg(struct ff_msg *msg, uint16_t proc_id)
msg->result = 0;
msg->ngctl.ret = ret;
}
}
#endif

rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
#ifdef FF_IPFW
static inline void
handle_ipfw_msg(struct ff_msg *msg)
{
int fd, ret;
fd = ff_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (fd < 0) {
ret = -1;
goto done;
}

switch (msg->ipfw.cmd) {
case FF_IPFW_GET:
ret = ff_getsockopt(fd, msg->ipfw.level,
msg->ipfw.optname, msg->ipfw.optval,
msg->ipfw.optlen);
break;
case FF_IPFW_SET:
ret = ff_setsockopt(fd, msg->ipfw.level,
msg->ipfw.optname, msg->ipfw.optval,
*(msg->ipfw.optlen));
break;
default:
ret = -1;
errno = ENOTSUP;
break;
}

ff_close(fd);

done:
if (ret < 0) {
msg->result = errno;
} else {
msg->result = 0;
}
}
#endif

static inline void
handle_default_msg(struct ff_msg *msg, uint16_t proc_id)
handle_default_msg(struct ff_msg *msg)
{
msg->result = ENOTSUP;
rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

static inline void
handle_msg(struct ff_msg *msg, uint16_t proc_id)
{
switch (msg->msg_type) {
case FF_SYSCTL:
handle_sysctl_msg(msg, proc_id);
handle_sysctl_msg(msg);
break;
case FF_IOCTL:
handle_ioctl_msg(msg, proc_id);
handle_ioctl_msg(msg);
break;
case FF_ROUTE:
handle_route_msg(msg, proc_id);
handle_route_msg(msg);
break;
case FF_TOP:
handle_top_msg(msg, proc_id);
handle_top_msg(msg);
break;
#ifdef FF_NETGRAPH
case FF_NGCTL:
handle_ngctl_msg(msg, proc_id);
handle_ngctl_msg(msg);
break;
#endif
#ifdef FF_IPFW
case FF_IPFW_CTL:
handle_ipfw_msg(msg);
break;
#endif
default:
handle_default_msg(msg, proc_id);
handle_default_msg(msg);
break;
}
rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
}

static inline int
Expand Down
39 changes: 39 additions & 0 deletions lib/ff_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,11 @@ securelevel_gt(struct ucred *cr, int level)
return (0);
}

int
securelevel_ge(struct ucred *cr, int level)
{
return (0);
}

/**
* @brief Send a 'notification' to userland, using standard ways
Expand Down Expand Up @@ -1140,3 +1145,37 @@ getcredhostid(struct ucred *cred, unsigned long *hostid)
{
*hostid = 0;
}

/*
* Check if gid is a member of the group set.
*/
int
groupmember(gid_t gid, struct ucred *cred)
{
int l;
int h;
int m;

if (cred->cr_groups[0] == gid)
return(1);

/*
* If gid was not our primary group, perform a binary search
* of the supplemental groups. This is possible because we
* sort the groups in crsetgroups().
*/
l = 1;
h = cred->cr_ngroups;
while (l < h) {
m = l + ((h - l) / 2);
if (cred->cr_groups[m] < gid)
l = m + 1;
else
h = m;
}
if ((l < cred->cr_ngroups) && (cred->cr_groups[l] == gid))
return (1);

return (0);
}

15 changes: 15 additions & 0 deletions lib/ff_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum FF_MSG_TYPE {
FF_ROUTE,
FF_TOP,
FF_NGCTL,
FF_IPFW_CTL,
};

struct ff_sysctl_args {
Expand Down Expand Up @@ -78,6 +79,19 @@ struct ff_ngctl_args {
void *data;
};

enum FF_IPFW_CMD {
FF_IPFW_GET,
FF_IPFW_SET,
};

struct ff_ipfw_args {
int cmd;
int level;
int optname;
void *optval;
socklen_t *optlen;
};

#define MAX_MSG_BUF_SIZE 10240

/* structure of ipc msg */
Expand All @@ -96,6 +110,7 @@ struct ff_msg {
struct ff_route_args route;
struct ff_top_args top;
struct ff_ngctl_args ngctl;
struct ff_ipfw_args ipfw;
};
} __attribute__((packed)) __rte_cache_aligned;

Expand Down
4 changes: 2 additions & 2 deletions lib/ff_syscall_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ ff_getsockopt(int s, int level, int optname, void *optval,
}

if ((rc = kern_getsockopt(curthread, s, level, optname,
optval, UIO_SYSSPACE, optlen)))
optval, UIO_USERSPACE, optlen)))
goto kern_fail;

return (rc);
Expand All @@ -410,7 +410,7 @@ ff_setsockopt(int s, int level, int optname, const void *optval,
}

if ((rc = kern_setsockopt(curthread, s, level, optname,
__DECONST(void *, optval), UIO_SYSSPACE, optlen)))
__DECONST(void *, optval), UIO_USERSPACE, optlen)))
goto kern_fail;

return (rc);
Expand Down
1 change: 1 addition & 0 deletions lib/opt/opt_bpf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define WITHOUT_BPF 1
1 change: 1 addition & 0 deletions lib/opt/opt_ipdivert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//#define IPDIVERT 1
12 changes: 12 additions & 0 deletions lib/opt/opt_ipfw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//sets default policy to pass what is not explicitly denied
#define IPFIREWALL_DEFAULT_TO_ACCEPT 1

//enables logging for rules with log keyword
//#define IPFIREWALL_VERBOSE 1

//limits number of logged packets per-entry
//#define IPFIREWALL_VERBOSE_LIMIT 5

//enables NAT
//#define IPFIREWALL_NAT 1

2 changes: 1 addition & 1 deletion tools/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl
SUBDIRS=compat libutil libmemstat libxo libnetgraph sysctl ifconfig route top netstat ngctl ipfw

all:
for d in $(SUBDIRS); do ( cd $$d; $(MAKE) all ) ; done
Expand Down
Loading

0 comments on commit b37139c

Please sign in to comment.