From patchwork Fri Feb 23 19:32:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Donald Sharp X-Patchwork-Id: 877265 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="HArXo4iZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zp1bb5BzDz9ryL for ; Sat, 24 Feb 2018 06:33:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754701AbeBWTdN (ORCPT ); Fri, 23 Feb 2018 14:33:13 -0500 Received: from mail-qk0-f195.google.com ([209.85.220.195]:33565 "EHLO mail-qk0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754680AbeBWTc4 (ORCPT ); Fri, 23 Feb 2018 14:32:56 -0500 Received: by mail-qk0-f195.google.com with SMTP id f25so12116397qkm.0 for ; Fri, 23 Feb 2018 11:32:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=e7JCgxGqidERwDYeO0VRd1XTP6EnLPJZbAy9qY450q8=; b=HArXo4iZOSFRW0x/kD9hcFBWnL7y/pWZotsejxVTO05M6jN1E+1T5ol+NqWYveEoP8 aunapc1JAslVFTi+IMG+7ngSX7bzv//QcfbaSQyYhIy4tIuCw2etyki7BSl6A8tAfHTH yJ1kQ0T/gHsMRFHUn8KlCYX0Ro74suw9/8zVQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=e7JCgxGqidERwDYeO0VRd1XTP6EnLPJZbAy9qY450q8=; b=Ec2YTNot1AHNB1YdDyTKAkmguU5cn5VjMyoA78nVhYKe0UKnCMAHta4u+lEWuhLp7u rVKlRFI8eRRocnnWAgmTD1aHWC1J9OtP/mqpWcopC9PKCcyW7tJRvfaST35+NWB//lvq wd4rg2cqnHNNbCzX213e0ZDmjTtDMycJM2iKnwaSc7Rc+JOlFsEu/OP2v5QRusMxmQNY EVSSaJYWPxebjVXXIPEI3PhXQotnNXntDFwfTZECCZieYA4rf7r04ux7OwRplyPhIeUX 6sJRJvapL1G/gQ64p/rg53xyyK2cG5hOe8x6WWRcviClegjsSwP1iNwGV4xEoNHsTMag hU2A== X-Gm-Message-State: APf1xPDOkyak8SlI4u+UmiTGAAqdKYx4SIPskmEPaJ5K3F3A/DDwzrll DSiHLcynNb+CqahW5DRp00bo97DV X-Google-Smtp-Source: AG47ELuQoIQXqEPbDr3lhCdRbElKpwbHYwfKXEjlZygoDgNTPsbm8D6v9shuoas/hOCFWEUG4Sr8qw== X-Received: by 10.55.16.13 with SMTP id a13mr4422167qkh.169.1519414375341; Fri, 23 Feb 2018 11:32:55 -0800 (PST) Received: from robot.nc.rr.com (cpe-2606-A000-111D-803E-CF1-EE96-732C-4D5.dyn6.twc.com. [2606:a000:111d:803e:cf1:ee96:732c:4d5]) by smtp.googlemail.com with ESMTPSA id t58sm1983498qtc.19.2018.02.23.11.32.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 23 Feb 2018 11:32:54 -0800 (PST) From: Donald Sharp To: netdev@vger.kernel.org, dsahern@gmail.com Subject: [PATCH v3 iproute2-next 1/3] ip: Use the `struct fib_rule_hdr` for rules Date: Fri, 23 Feb 2018 14:32:46 -0500 Message-Id: <20180223193248.16744-2-sharpd@cumulusnetworks.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180221015348.32646-1-sharpd@cumulusnetworks.com> References: <20180221015348.32646-1-sharpd@cumulusnetworks.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The iprule.c code was using `struct rtmsg` as the data type to pass into the kernel for the netlink message. While 'struct rtmsg' and `struct fib_rule_hdr` are the same size and mostly the same, we should use the correct data structure. This commit translates the data structures to have iprule.c use the correct one. Additionally copy over the modified fib_rules.h file Signed-off-by: Donald Sharp --- include/uapi/linux/fib_rules.h | 1 + ip/iprule.c | 128 +++++++++++++++++++++-------------------- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h index 2b642bf9..9477c3af 100644 --- a/include/uapi/linux/fib_rules.h +++ b/include/uapi/linux/fib_rules.h @@ -58,6 +58,7 @@ enum { FRA_PAD, FRA_L3MDEV, /* iif or oif is l3mdev goto its table */ FRA_UID_RANGE, /* UID range */ + FRA_PROTOCOL, __FRA_MAX }; diff --git a/ip/iprule.c b/ip/iprule.c index a3abf2f6..94356bf8 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -73,25 +73,33 @@ static struct inet_prefix dst; } filter; +static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb) +{ + __u32 table = frh->table; + if (tb[RTA_TABLE]) + table = rta_getattr_u32(tb[RTA_TABLE]); + return table; +} + static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) { - struct rtmsg *r = NLMSG_DATA(n); + struct fib_rule_hdr *frh = NLMSG_DATA(n); __u32 table; - if (preferred_family != AF_UNSPEC && r->rtm_family != preferred_family) + if (preferred_family != AF_UNSPEC && frh->family != preferred_family) return false; if (filter.prefmask && filter.pref ^ (tb[FRA_PRIORITY] ? rta_getattr_u32(tb[FRA_PRIORITY]) : 0)) return false; - if (filter.not && !(r->rtm_flags & FIB_RULE_INVERT)) + if (filter.not && !(frh->flags & FIB_RULE_INVERT)) return false; if (filter.src.family) { inet_prefix *f_src = &filter.src; - if (f_src->family != r->rtm_family || - f_src->bitlen > r->rtm_src_len) + if (f_src->family != frh->family || + f_src->bitlen > frh->src_len) return false; if (inet_addr_match_rta(f_src, tb[FRA_SRC])) @@ -101,15 +109,15 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) if (filter.dst.family) { inet_prefix *f_dst = &filter.dst; - if (f_dst->family != r->rtm_family || - f_dst->bitlen > r->rtm_dst_len) + if (f_dst->family != frh->family || + f_dst->bitlen > frh->dst_len) return false; if (inet_addr_match_rta(f_dst, tb[FRA_DST])) return false; } - if (filter.tosmask && filter.tos ^ r->rtm_tos) + if (filter.tosmask && filter.tos ^ frh->tos) return false; if (filter.fwmark) { @@ -159,7 +167,7 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return false; } - table = rtm_get_table(r, tb); + table = frh_get_table(frh, tb); if (filter.tb > 0 && filter.tb ^ table) return false; @@ -169,7 +177,7 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE *)arg; - struct rtmsg *r = NLMSG_DATA(n); + struct fib_rule_hdr *frh = NLMSG_DATA(n); int len = n->nlmsg_len; int host_len = -1; __u32 table; @@ -180,13 +188,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE) return 0; - len -= NLMSG_LENGTH(sizeof(*r)); + len -= NLMSG_LENGTH(sizeof(*frh)); if (len < 0) return -1; - parse_rtattr(tb, FRA_MAX, RTM_RTA(r), len); + parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len); - host_len = af_bit_len(r->rtm_family); + host_len = af_bit_len(frh->family); if (!filter_nlmsg(n, tb, host_len)) return 0; @@ -200,41 +208,41 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) else fprintf(fp, "0:\t"); - if (r->rtm_flags & FIB_RULE_INVERT) + if (frh->flags & FIB_RULE_INVERT) fprintf(fp, "not "); if (tb[FRA_SRC]) { - if (r->rtm_src_len != host_len) { + if (frh->src_len != host_len) { fprintf(fp, "from %s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[FRA_SRC]), - r->rtm_src_len); + rt_addr_n2a_rta(frh->family, tb[FRA_SRC]), + frh->src_len); } else { fprintf(fp, "from %s ", - format_host_rta(r->rtm_family, tb[FRA_SRC])); + format_host_rta(frh->family, tb[FRA_SRC])); } - } else if (r->rtm_src_len) { - fprintf(fp, "from 0/%d ", r->rtm_src_len); + } else if (frh->src_len) { + fprintf(fp, "from 0/%d ", frh->src_len); } else { fprintf(fp, "from all "); } if (tb[FRA_DST]) { - if (r->rtm_dst_len != host_len) { + if (frh->dst_len != host_len) { fprintf(fp, "to %s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[FRA_DST]), - r->rtm_dst_len); + rt_addr_n2a_rta(frh->family, tb[FRA_DST]), + frh->dst_len); } else { fprintf(fp, "to %s ", - format_host_rta(r->rtm_family, tb[FRA_DST])); + format_host_rta(frh->family, tb[FRA_DST])); } - } else if (r->rtm_dst_len) { - fprintf(fp, "to 0/%d ", r->rtm_dst_len); + } else if (frh->dst_len) { + fprintf(fp, "to 0/%d ", frh->dst_len); } - if (r->rtm_tos) { + if (frh->tos) { SPRINT_BUF(b1); fprintf(fp, "tos %s ", - rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); + rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1))); } if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { @@ -252,13 +260,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (tb[FRA_IFNAME]) { fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME])); - if (r->rtm_flags & FIB_RULE_IIF_DETACHED) + if (frh->flags & FIB_RULE_IIF_DETACHED) fprintf(fp, "[detached] "); } if (tb[FRA_OIFNAME]) { fprintf(fp, "oif %s ", rta_getattr_str(tb[FRA_OIFNAME])); - if (r->rtm_flags & FIB_RULE_OIF_DETACHED) + if (frh->flags & FIB_RULE_OIF_DETACHED) fprintf(fp, "[detached] "); } @@ -273,7 +281,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "uidrange %u-%u ", r->start, r->end); } - table = rtm_get_table(r, tb); + table = frh_get_table(frh, tb); if (table) { fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1))); @@ -308,26 +316,26 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) rtnl_rtrealm_n2a(to, b1, sizeof(b1))); } - if (r->rtm_type == RTN_NAT) { + if (frh->action == RTN_NAT) { if (tb[RTA_GATEWAY]) { fprintf(fp, "map-to %s ", - format_host_rta(r->rtm_family, + format_host_rta(frh->family, tb[RTA_GATEWAY])); } else fprintf(fp, "masquerade"); - } else if (r->rtm_type == FR_ACT_GOTO) { + } else if (frh->action == FR_ACT_GOTO) { fprintf(fp, "goto "); if (tb[FRA_GOTO]) fprintf(fp, "%u", rta_getattr_u32(tb[FRA_GOTO])); else fprintf(fp, "none"); - if (r->rtm_flags & FIB_RULE_UNRESOLVED) + if (frh->flags & FIB_RULE_UNRESOLVED) fprintf(fp, " [unresolved]"); - } else if (r->rtm_type == FR_ACT_NOP) + } else if (frh->action == FR_ACT_NOP) fprintf(fp, "nop"); - else if (r->rtm_type != RTN_UNICAST) + else if (frh->action != FR_ACT_TO_TBL) fprintf(fp, "%s", - rtnl_rtntype_n2a(r->rtm_type, + rtnl_rtntype_n2a(frh->action, b1, sizeof(b1))); fprintf(fp, "\n"); @@ -373,15 +381,15 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { struct rtnl_handle rth2; - struct rtmsg *r = NLMSG_DATA(n); + struct fib_rule_hdr *frh = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[FRA_MAX+1]; - len -= NLMSG_LENGTH(sizeof(*r)); + len -= NLMSG_LENGTH(sizeof(*frh)); if (len < 0) return -1; - parse_rtattr(tb, FRA_MAX, RTM_RTA(r), len); + parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len); if (tb[FRA_PRIORITY]) { n->nlmsg_type = RTM_DELRULE; @@ -577,21 +585,19 @@ static int iprule_modify(int cmd, int argc, char **argv) __u32 tid = 0; struct { struct nlmsghdr n; - struct rtmsg r; + struct fib_rule_hdr frh; char buf[1024]; } req = { .n.nlmsg_type = cmd, - .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), .n.nlmsg_flags = NLM_F_REQUEST, - .r.rtm_family = preferred_family, - .r.rtm_protocol = RTPROT_BOOT, - .r.rtm_scope = RT_SCOPE_UNIVERSE, - .r.rtm_type = RTN_UNSPEC, + .frh.family = preferred_family, + .frh.action = FR_ACT_UNSPEC, }; if (cmd == RTM_NEWRULE) { req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL; - req.r.rtm_type = RTN_UNICAST; + req.frh.action = FR_ACT_TO_TBL; } if (cmd == RTM_DELRULE && argc == 0) { @@ -601,21 +607,21 @@ static int iprule_modify(int cmd, int argc, char **argv) while (argc > 0) { if (strcmp(*argv, "not") == 0) { - req.r.rtm_flags |= FIB_RULE_INVERT; + req.frh.flags |= FIB_RULE_INVERT; } else if (strcmp(*argv, "from") == 0) { inet_prefix dst; NEXT_ARG(); - get_prefix(&dst, *argv, req.r.rtm_family); - req.r.rtm_src_len = dst.bitlen; + get_prefix(&dst, *argv, req.frh.family); + req.frh.src_len = dst.bitlen; addattr_l(&req.n, sizeof(req), FRA_SRC, &dst.data, dst.bytelen); } else if (strcmp(*argv, "to") == 0) { inet_prefix dst; NEXT_ARG(); - get_prefix(&dst, *argv, req.r.rtm_family); - req.r.rtm_dst_len = dst.bitlen; + get_prefix(&dst, *argv, req.frh.family); + req.frh.dst_len = dst.bitlen; addattr_l(&req.n, sizeof(req), FRA_DST, &dst.data, dst.bytelen); } else if (matches(*argv, "preference") == 0 || @@ -634,7 +640,7 @@ static int iprule_modify(int cmd, int argc, char **argv) NEXT_ARG(); if (rtnl_dsfield_a2n(&tos, *argv)) invarg("TOS value is invalid\n", *argv); - req.r.rtm_tos = tos; + req.frh.tos = tos; } else if (strcmp(*argv, "fwmark") == 0) { char *slash; __u32 fwmark, fwmask; @@ -667,9 +673,9 @@ static int iprule_modify(int cmd, int argc, char **argv) if (rtnl_rttable_a2n(&tid, *argv)) invarg("invalid table ID\n", *argv); if (tid < 256) - req.r.rtm_table = tid; + req.frh.table = tid; else { - req.r.rtm_table = RT_TABLE_UNSPEC; + req.frh.table = RT_TABLE_UNSPEC; addattr32(&req.n, sizeof(req), FRA_TABLE, tid); } table_ok = 1; @@ -724,7 +730,7 @@ static int iprule_modify(int cmd, int argc, char **argv) fprintf(stderr, "Warning: route NAT is deprecated\n"); addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); - req.r.rtm_type = RTN_NAT; + req.frh.action = RTN_NAT; } else { int type; @@ -746,7 +752,7 @@ static int iprule_modify(int cmd, int argc, char **argv) type = FR_ACT_NOP; else if (rtnl_rtntype_a2n(&type, *argv)) invarg("Failed to parse rule type", *argv); - req.r.rtm_type = type; + req.frh.action = type; table_ok = 1; } argc--; @@ -759,11 +765,11 @@ static int iprule_modify(int cmd, int argc, char **argv) return -EINVAL; } - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = AF_INET; + if (req.frh.family == AF_UNSPEC) + req.frh.family = AF_INET; if (!table_ok && cmd == RTM_NEWRULE) - req.r.rtm_table = RT_TABLE_MAIN; + req.frh.table = RT_TABLE_MAIN; if (rtnl_talk(&rth, &req.n, NULL) < 0) return -2;