From patchwork Thu Apr 20 16:05:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Lebleu X-Patchwork-Id: 752873 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w83f54jZFz9s4s for ; Fri, 21 Apr 2017 02:06:53 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="qpc6P26U"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gZzYvgUN"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Subject:References: In-Reply-To:Message-Id:Date:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=EjBnekMVjoBS9W9+gEcv2LcwluDXt+8ftafAKCUwFVQ=; b=qpc6P26UIinsbF N/Mlbx4CuzS2BGTNRV/m5OuMp4tidi7HWvjJB8R3GNAMKGYQuZYNm05ElkT83c9HnYUAnrx4IlntE 5ywDlJ/D9RwESXDNYmP4hvV3OWyKMBRQIfm4Xhc2YXw9obz2erdbp2djzwgCnm8j41QwKUWHepmgi X0YUL8T+i02a2fYG+zyyeMShJXrolKlZ1TpM534QtZRasgr+zWPV26nhpBHRa7jvLK4H3o021djV0 /y71tC4FPwaL+NkFsHK/4gOp7GLraWq9uOoEmpDQrm6wLJoVAnhNEFE/t90K/zN2FPdUA8qG8dxQI 0DXOIE6S2AZaz8Er3D5Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d1EbZ-0007Bm-29; Thu, 20 Apr 2017 16:06:49 +0000 Received: from mail-io0-x242.google.com ([2607:f8b0:4001:c06::242]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1d1Eb0-0006VZ-Bx for lede-dev@lists.infradead.org; Thu, 20 Apr 2017 16:06:17 +0000 Received: by mail-io0-x242.google.com with SMTP id x86so17909602ioe.3 for ; Thu, 20 Apr 2017 09:05:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qJ5LntMNJG+L07dI1XZ3LBkRWBGF7FUrYcipnD6qX4o=; b=gZzYvgUN+MH3TBD2qwAQN+c65u4Y+dS/XtTtlWDr/wIhSDmT8lwdod6rhh1+lLb/U7 y7ORM1bjPcaQFV2KeJPBYp1W8jbSBDBzw1COIWXpM/qp2NPxN8HgyxMux+ZCIIZzCBAg a0IVZpZ3xc6qRpgm1DGa5XbaDV/oZTLXJGUIu/VDGc97sQOrZwUmlPBLdeA5OTOXKPNk 2iss57GWpkuBe8Sf62QjFo1yg3tYq16/MijAWTS5u+Dq/6T977rDtnEc2Mscz29tbaQk xXau+octavG+fdP/pym0vxPb2zP2EQNja+fmIlpgvtDhLOK+PaVq+wFn/cJjvK9h5/3u RaWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qJ5LntMNJG+L07dI1XZ3LBkRWBGF7FUrYcipnD6qX4o=; b=VyUybJTQM/t2NfT/+8qTGH7Smb/lm/WUO1acTDPYCDw30I6uy4zxE3s4PRJcJhle/Q 7iGGCK7eD59so3t0iqJAj07EEKKVjwwImNL1VJCvV1A05VX/LYkTGcj7iY5qrnU6PkG1 vCJJlxV6tp3WpoW4eTm8Qi5XpzKuthdp0DkFzE0jxC7v5p5EGjRIUtHq5XFypPpvVNA5 hivpGHa3dldtKkOs3UxH9Dd9xZFZb9vwuSLR6N6k+JgW12c0Aq0ud5eFQNUIjlVpcplc 3hMCufAXIasr27uxbXQCAhLzLUnzdhAaWRVpGL0aogb6vn8v2YL7KSYGEJDnSfOT1DYB Xp7g== X-Gm-Message-State: AN3rC/6N2+jjFGHWiESVdSY5Ts9dSwP1hVKXfQpBhQIvXBRTTEm9PoSs ASHmaIdPxitrIA== X-Received: by 10.36.73.31 with SMTP id z31mr4631186ita.2.1492704353083; Thu, 20 Apr 2017 09:05:53 -0700 (PDT) Received: from smtp.gmail.com (14.125.146.82.ipv4.evonet.be. [82.146.125.14]) by smtp.gmail.com with ESMTPSA id u191sm7931652ita.15.2017.04.20.09.05.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 20 Apr 2017 09:05:52 -0700 (PDT) From: Pierre Lebleu To: lede-dev@lists.infradead.org Date: Thu, 20 Apr 2017 18:05:38 +0200 Message-Id: <1492704342-24042-3-git-send-email-pme.lebleu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1492704342-24042-1-git-send-email-pme.lebleu@gmail.com> References: <1492704342-24042-1-git-send-email-pme.lebleu@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170420_090614_517066_92872BB9 X-CRM114-Status: GOOD ( 12.42 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (pme.lebleu[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Subject: [LEDE-DEV] [PATCH 3/7] firewall3: add UBUS support for redirect sections X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Pierre Lebleu , jow@mein.io MIME-Version: 1.0 Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org It gives the ability to create redirect rules via procd services and netifd interface firewall data. Signed-off-by: Pierre Lebleu --- main.c | 2 +- redirects.c | 108 ++++++++++++++++++++++++++++++++++++++++++----------------- redirects.h | 10 ++++-- 3 files changed, 85 insertions(+), 35 deletions(-) diff --git a/main.c b/main.c index e38963d..5888ab5 100644 --- a/main.c +++ b/main.c @@ -104,7 +104,7 @@ build_state(bool runtime) fw3_load_ipsets(state, p); fw3_load_zones(state, p); fw3_load_rules(state, p, b.head); - fw3_load_redirects(state, p); + fw3_load_redirects(state, p, b.head); fw3_load_snats(state, p, b.head); fw3_load_forwards(state, p); fw3_load_includes(state, p); diff --git a/redirects.c b/redirects.c index a657b6d..b9ad3d5 100644 --- a/redirects.c +++ b/redirects.c @@ -175,35 +175,72 @@ check_local(struct uci_element *e, struct fw3_redirect *redir, return redir->local; } +static struct fw3_redirect * +fw3_alloc_redirect(struct fw3_state *state) +{ + struct fw3_redirect *redir; + + redir = calloc(1, sizeof(*redir)); + if (!redir) + return NULL; + + INIT_LIST_HEAD(&redir->proto); + INIT_LIST_HEAD(&redir->mac_src); + + redir->enabled = true; + redir->reflection = true; + + list_add_tail(&redir->list, &state->redirects); + + return redir; +} + void -fw3_load_redirects(struct fw3_state *state, struct uci_package *p) +fw3_load_redirects(struct fw3_state *state, struct uci_package *p, + struct blob_attr *a) { struct uci_section *s; struct uci_element *e; - struct fw3_redirect *redir; - + struct fw3_redirect *redir, *n; + struct blob_attr *entry, *opt; + unsigned rem, orem; bool valid; INIT_LIST_HEAD(&state->redirects); - uci_foreach_element(&p->sections, e) + blob_for_each_attr(entry, a, rem) { - s = uci_to_section(e); + const char *type = NULL; + const char *name = "ubus redirect"; + blobmsg_for_each_attr(opt, entry, orem) + if (!strcmp(blobmsg_name(opt), "type")) + type = blobmsg_get_string(opt); + else if (!strcmp(blobmsg_name(opt), "name")) + name = blobmsg_get_string(opt); + + if (!type || strcmp(type, "redirect")) + continue; - if (strcmp(s->type, "redirect")) + if (!(redir = fw3_alloc_redirect(state))) continue; - redir = calloc(1, sizeof(*redir)); - if (!redir) + if (!fw3_parse_blob_options(redir, fw3_redirect_opts, entry, name)) + { + warn("%s skipped due to invalid options\n", name); + fw3_free_redirect(redir); continue; + } + } - INIT_LIST_HEAD(&redir->proto); - INIT_LIST_HEAD(&redir->mac_src); + uci_foreach_element(&p->sections, e) + { + s = uci_to_section(e); - redir->enabled = true; - redir->reflection = true; + if (strcmp(s->type, "redirect")) + continue; - valid = false; + if (!(redir = fw3_alloc_redirect(state))) + continue; if (!fw3_parse_options(redir, fw3_redirect_opts, s)) { @@ -211,7 +248,10 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) fw3_free_redirect(redir); continue; } + } + list_for_each_entry_safe(redir, n, &state->redirects, list) + { if (!redir->enabled) { fw3_free_redirect(redir); @@ -220,34 +260,37 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) if (redir->src.invert) { - warn_elem(e, "must not have an inverted source"); + warn("%s must not have an inverted source", redir->name); fw3_free_redirect(redir); continue; } else if (redir->src.set && !redir->src.any && !(redir->_src = fw3_lookup_zone(state, redir->src.name))) { - warn_elem(e, "refers to not existing zone '%s'", redir->src.name); + warn("%s refers to not existing zone '%s'", redir->name, + redir->src.name); fw3_free_redirect(redir); continue; } else if (redir->dest.set && !redir->dest.any && !(redir->_dest = fw3_lookup_zone(state, redir->dest.name))) { - warn_elem(e, "refers to not existing zone '%s'", redir->dest.name); + warn("%s refers to not existing zone '%s'", redir->name, + redir->dest.name); fw3_free_redirect(redir); continue; } else if (redir->ipset.set && state->disable_ipsets) { - warn_elem(e, "skipped due to disabled ipset support"); + warn("%s skipped due to disabled ipset support", redir->name); fw3_free_redirect(redir); continue; } else if (redir->ipset.set && !(redir->ipset.ptr = fw3_lookup_ipset(state, redir->ipset.name))) { - warn_elem(e, "refers to unknown ipset '%s'", redir->ipset.name); + warn("%s refers to unknown ipset '%s'", redir->name, + redir->ipset.name); fw3_free_redirect(redir); continue; } @@ -260,21 +303,26 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) if (redir->target == FW3_FLAG_UNSPEC) { - warn_elem(e, "has no target specified, defaulting to DNAT"); + warn("%s has no target specified, defaulting to DNAT", + redir->name); redir->target = FW3_FLAG_DNAT; } else if (redir->target < FW3_FLAG_DNAT || redir->target > FW3_FLAG_SNAT) { - warn_elem(e, "has invalid target specified, defaulting to DNAT"); + warn("%s has invalid target specified, defaulting to DNAT", + redir->name); redir->target = FW3_FLAG_DNAT; } + valid = false; + if (redir->target == FW3_FLAG_DNAT) { if (redir->src.any) - warn_elem(e, "must not have source '*' for DNAT target"); + warn("%s must not have source '*' for DNAT target", + redir->name); else if (!redir->_src) - warn_elem(e, "has no source specified"); + warn("%s has no source specified", redir->name); else { set(redir->_src->flags, FW3_FAMILY_V4, redir->target); @@ -283,8 +331,8 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) if (!check_local(e, redir, state) && !redir->dest.set && resolve_dest(e, redir, state)) { - warn_elem(e, "does not specify a destination, assuming '%s'", - redir->dest.name); + warn("%s does not specify a destination, assuming '%s'", + redir->name, redir->dest.name); } if (redir->reflection && redir->_dest && redir->_src->masq) @@ -298,13 +346,13 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) else { if (redir->dest.any) - warn_elem(e, "must not have destination '*' for SNAT target"); + warn("%s must not have destination '*' for SNAT target", redir->name); else if (!redir->_dest) - warn_elem(e, "has no destination specified"); + warn("%s has no destination specified", redir->name); else if (!redir->ip_dest.set) - warn_elem(e, "has no src_dip option specified"); + warn("%s has no src_dip option specified", redir->name); else if (!list_empty(&redir->mac_src)) - warn_elem(e, "must not use 'src_mac' option for SNAT target"); + warn("%s must not use 'src_mac' option for SNAT target", redir->name); else { set(redir->_dest->flags, FW3_FAMILY_V4, redir->target); @@ -314,7 +362,7 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) if (list_empty(&redir->proto)) { - warn_elem(e, "does not specify a protocol, assuming TCP+UDP"); + warn("%s does not specify a protocol, assuming TCP+UDP", redir->name); fw3_parse_protocol(&redir->proto, "tcpudp", true); } @@ -326,8 +374,6 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) if (!redir->port_redir.set) redir->port_redir = redir->port_dest; - - list_add_tail(&redir->list, &state->redirects); } } diff --git a/redirects.h b/redirects.h index b52d8c3..ac625f4 100644 --- a/redirects.h +++ b/redirects.h @@ -27,11 +27,15 @@ extern const struct fw3_option fw3_redirect_opts[]; -void fw3_load_redirects(struct fw3_state *state, struct uci_package *p); +void fw3_load_redirects(struct fw3_state *state, struct uci_package *p, + struct blob_attr *a); void fw3_print_redirects(struct fw3_ipt_handle *handle, struct fw3_state *state); -#define fw3_free_redirect(redir) \ - fw3_free_object(redir, fw3_redirect_opts) +static inline void fw3_free_redirect(struct fw3_redirect *redir) +{ + list_del(&redir->list); + fw3_free_object(redir, fw3_redirect_opts); +} #endif