summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_fw2.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2006-08-17 22:49:50 +0000
committerjulian <julian@FreeBSD.org>2006-08-17 22:49:50 +0000
commitff9e3178175b11cd7809c6ada10182a3554f2397 (patch)
tree13d3659c8c675327f2a39e3b2a6d78953ca0abc2 /sys/netinet/ip_fw2.c
parent59cd950be143bf9ff3f67c3a051757216f0b9933 (diff)
downloadFreeBSD-src-ff9e3178175b11cd7809c6ada10182a3554f2397.zip
FreeBSD-src-ff9e3178175b11cd7809c6ada10182a3554f2397.tar.gz
Allow ipfw to forward to a destination that is specified by a table.
for example: fwd tablearg ip from any to table(1) where table 1 has entries of the form: 1.1.1.0/24 10.2.3.4 208.23.2.0/24 router2 This allows trivial implementation of a secondary routing table implemented in the firewall layer. I expect more work (under discussion with Glebius) to follow this to clean up some of the messy parts of ipfw related to tables. Reviewed by: Glebius MFC after: 1 month
Diffstat (limited to 'sys/netinet/ip_fw2.c')
-rw-r--r--sys/netinet/ip_fw2.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index e9b24df..47fc7f6 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -738,7 +738,7 @@ static u_int64_t norule_counter; /* counter for ipfw_log(NULL...) */
*/
static void
ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
- struct mbuf *m, struct ifnet *oif, u_short offset)
+ struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg)
{
struct ether_header *eh = args->eh;
char *action;
@@ -831,9 +831,15 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
case O_FORWARD_IP: {
ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
int len;
+ struct in_addr dummyaddr;
+ if (sa->sa.sin_addr.s_addr == INADDR_ANY)
+ dummyaddr.s_addr = htonl(tablearg);
+ else
+ dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
len = snprintf(SNPARGS(action2, 0), "Forward to %s",
- inet_ntoa(sa->sa.sin_addr));
+ inet_ntoa(dummyaddr));
+
if (sa->sa.sin_port)
snprintf(SNPARGS(action2, len), ":%d",
sa->sa.sin_port);
@@ -2785,7 +2791,7 @@ check_body:
case O_LOG:
if (fw_verbose)
- ipfw_log(f, hlen, args, m, oif, offset);
+ ipfw_log(f, hlen, args, m, oif, offset, tablearg);
match = 1;
break;
@@ -3141,13 +3147,23 @@ check_body:
retval = IP_FW_DENY;
goto done;
- case O_FORWARD_IP:
+ case O_FORWARD_IP: {
+ struct sockaddr_in *sa;
+ sa = &(((ipfw_insn_sa *)cmd)->sa);
if (args->eh) /* not valid on layer2 pkts */
break;
- if (!q || dyn_dir == MATCH_FORWARD)
- args->next_hop =
- &((ipfw_insn_sa *)cmd)->sa;
+ if (!q || dyn_dir == MATCH_FORWARD) {
+ if (sa->sin_addr.s_addr == INADDR_ANY) {
+ bcopy(sa, &args->hopstore,
+ sizeof(*sa));
+ args->hopstore.sin_addr.s_addr = htonl(tablearg);
+ args->next_hop = &args->hopstore;
+ } else {
+ args->next_hop = sa;
+ }
+ }
retval = IP_FW_PASS;
+ }
goto done;
case O_NETGRAPH:
OpenPOWER on IntegriCloud