Date: Thu, 14 Mar 2019 22:28:50 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r345162 - head/sys/netpfil/ipfw Message-ID: <201903142228.x2EMSo2h059922@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Thu Mar 14 22:28:50 2019 New Revision: 345162 URL: https://svnweb.freebsd.org/changeset/base/345162 Log: - Add more flags to ip_fw_args. At this changeset only IPFW_ARGS_IN and IPFW_ARGS_OUT are utilized. They are intented to substitute the "dir" parameter that is often passes together with args. - Rename ip_fw_args.oif to ifp and now it is set to either input or output interface, depending on IPFW_ARGS_IN/OUT bit set. Modified: head/sys/netpfil/ipfw/ip_dn_io.c head/sys/netpfil/ipfw/ip_fw2.c head/sys/netpfil/ipfw/ip_fw_dynamic.c head/sys/netpfil/ipfw/ip_fw_log.c head/sys/netpfil/ipfw/ip_fw_nat.c head/sys/netpfil/ipfw/ip_fw_pfil.c head/sys/netpfil/ipfw/ip_fw_private.h Modified: head/sys/netpfil/ipfw/ip_dn_io.c ============================================================================== --- head/sys/netpfil/ipfw/ip_dn_io.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_dn_io.c Thu Mar 14 22:28:50 2019 (r345162) @@ -841,7 +841,7 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *f dt->rule = fwa->rule; dt->rule.info &= IPFW_ONEPASS; /* only keep this info */ dt->dn_dir = dir; - dt->ifp = fwa->oif; + dt->ifp = fwa->flags & IPFW_ARGS_OUT ? fwa->ifp : NULL; /* dt->output tame is updated as we move through */ dt->output_time = dn_cfg.curr_time; dt->iphdr_off = (dir & PROTO_LAYER2) ? ETHER_HDR_LEN : 0; Modified: head/sys/netpfil/ipfw/ip_fw2.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw2.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw2.c Thu Mar 14 22:28:50 2019 (r345162) @@ -1080,13 +1080,11 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a struct inpcbinfo *pi; struct ipfw_flow_id *id; struct inpcb *pcb, *inp; - struct ifnet *oif; int lookupflags; int match; id = &args->f_id; inp = args->inp; - oif = args->oif; /* * Check to see if the UDP or TCP stack supplied us with @@ -1124,16 +1122,16 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a if (*ugid_lookupp == 0) { if (id->addr_type == 6) { #ifdef INET6 - if (oif == NULL) + if (args->flags & IPFW_ARGS_IN) pcb = in6_pcblookup_mbuf(pi, &id->src_ip6, htons(id->src_port), &id->dst_ip6, htons(id->dst_port), - lookupflags, oif, args->m); + lookupflags, NULL, args->m); else pcb = in6_pcblookup_mbuf(pi, &id->dst_ip6, htons(id->dst_port), &id->src_ip6, htons(id->src_port), - lookupflags, oif, args->m); + lookupflags, args->ifp, args->m); #else *ugid_lookupp = -1; return (0); @@ -1141,16 +1139,16 @@ check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *a } else { src_ip.s_addr = htonl(id->src_ip); dst_ip.s_addr = htonl(id->dst_ip); - if (oif == NULL) + if (args->flags & IPFW_ARGS_IN) pcb = in_pcblookup_mbuf(pi, src_ip, htons(id->src_port), dst_ip, htons(id->dst_port), - lookupflags, oif, args->m); + lookupflags, NULL, args->m); else pcb = in_pcblookup_mbuf(pi, dst_ip, htons(id->dst_port), src_ip, htons(id->src_port), - lookupflags, oif, args->m); + lookupflags, args->ifp, args->m); } if (pcb != NULL) { INP_RLOCK_ASSERT(pcb); @@ -1263,8 +1261,7 @@ jump_linear(struct ip_fw_chain *chain, struct ip_fw *f * args->eh (in) Mac header if present, NULL for layer3 packet. * args->L3offset Number of bytes bypassed if we came from L2. * e.g. often sizeof(eh) ** NOTYET ** - * args->oif Outgoing interface, NULL if packet is incoming. - * The incoming interface is in the mbuf. (in) + * args->ifp Incoming or outgoing interface. * args->divert_rule (in/out) * Skip up to the first rule past this rule number; * upon return, non-zero port number for divert or tee. @@ -1331,17 +1328,9 @@ ipfw_chk(struct ip_fw_args *args) struct ucred *ucred_cache = NULL; #endif int ucred_lookup = 0; - - /* - * oif | args->oif If NULL, ipfw_chk has been called on the - * inbound path (ether_input, ip_input). - * If non-NULL, ipfw_chk has been called on the outbound path - * (ether_output, ip_output). - */ - struct ifnet *oif = args->oif; - int f_pos = 0; /* index of current rule in the array */ int retval = 0; + struct ifnet *oif, *iif; /* * hlen The length of the IP header. @@ -1724,6 +1713,15 @@ do { \ f_pos = 0; } + if (args->flags & IPFW_ARGS_IN) { + iif = args->ifp; + oif = NULL; + } else { + MPASS(args->flags & IPFW_ARGS_OUT); + iif = m->m_pkthdr.rcvif; + oif = args->ifp; + } + /* * Now scan the rules, and parse microinstructions for each rule. * We have two nested loops and an inner switch. Sometimes we @@ -1820,8 +1818,8 @@ do { \ break; case O_RECV: - match = iface_match(m->m_pkthdr.rcvif, - (ipfw_insn_if *)cmd, chain, &tablearg); + match = iface_match(iif, (ipfw_insn_if *)cmd, + chain, &tablearg); break; case O_XMIT: @@ -1830,9 +1828,8 @@ do { \ break; case O_VIA: - match = iface_match(oif ? oif : - m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, - chain, &tablearg); + match = iface_match(args->ifp, + (ipfw_insn_if *)cmd, chain, &tablearg); break; case O_MACADDR2: @@ -2334,7 +2331,7 @@ do { \ case O_LOG: ipfw_log(chain, f, hlen, args, m, - oif, offset | ip6f_mf, tablearg, ip); + offset | ip6f_mf, tablearg, ip); match = 1; break; @@ -2344,16 +2341,14 @@ do { \ case O_VERREVPATH: /* Outgoing packets automatically pass/match */ - match = ((oif != NULL) || - (m->m_pkthdr.rcvif == NULL) || + match = (args->flags & IPFW_ARGS_OUT || ( #ifdef INET6 is_ipv6 ? verify_path6(&(args->f_id.src_ip6), - m->m_pkthdr.rcvif, args->f_id.fib) : + iif, args->f_id.fib) : #endif - verify_path(src_ip, m->m_pkthdr.rcvif, - args->f_id.fib))); + verify_path(src_ip, iif, args->f_id.fib))); break; case O_VERSRCREACH: @@ -2379,12 +2374,10 @@ do { \ match = #ifdef INET6 is_ipv6 ? verify_path6( - &(args->f_id.src_ip6), - m->m_pkthdr.rcvif, + &(args->f_id.src_ip6), iif, args->f_id.fib) : #endif - verify_path(src_ip, - m->m_pkthdr.rcvif, + verify_path(src_ip, iif, args->f_id.fib); else match = 1; Modified: head/sys/netpfil/ipfw/ip_fw_dynamic.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_dynamic.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw_dynamic.c Thu Mar 14 22:28:50 2019 (r345162) @@ -1173,12 +1173,9 @@ dyn_getscopeid(const struct ip_fw_args *args) * determine the scope zone id to resolve address scope ambiguity. */ if (IN6_IS_ADDR_LINKLOCAL(&args->f_id.src_ip6) || - IN6_IS_ADDR_LINKLOCAL(&args->f_id.dst_ip6)) { - MPASS(args->oif != NULL || - args->m->m_pkthdr.rcvif != NULL); - return (in6_getscopezone(args->oif != NULL ? args->oif: - args->m->m_pkthdr.rcvif, IPV6_ADDR_SCOPE_LINKLOCAL)); - } + IN6_IS_ADDR_LINKLOCAL(&args->f_id.dst_ip6)) + return (in6_getscopezone(args->ifp, IPV6_ADDR_SCOPE_LINKLOCAL)); + return (0); } Modified: head/sys/netpfil/ipfw/ip_fw_log.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_log.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw_log.c Thu Mar 14 22:28:50 2019 (r345162) @@ -99,7 +99,7 @@ __FBSDID("$FreeBSD$"); */ void ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, - struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif, + struct ip_fw_args *args, struct mbuf *m, u_short offset, uint32_t tablearg, struct ip *ip) { char *action; @@ -405,19 +405,14 @@ ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u } } #ifdef __FreeBSD__ - if (oif || m->m_pkthdr.rcvif) - log(LOG_SECURITY | LOG_INFO, - "ipfw: %d %s %s %s via %s%s\n", - f ? f->rulenum : -1, - action, proto, oif ? "out" : "in", - oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname, - fragment); - else + log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s %s via %s%s\n", + f ? f->rulenum : -1, action, proto, + args->flags & IPFW_ARGS_OUT ? "out" : "in", args->ifp->if_xname, + fragment); +#else + log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s [no if info]%s\n", + f ? f->rulenum : -1, action, proto, fragment); #endif - log(LOG_SECURITY | LOG_INFO, - "ipfw: %d %s %s [no if info]%s\n", - f ? f->rulenum : -1, - action, proto, fragment); if (limit_reached) log(LOG_SECURITY | LOG_NOTICE, "ipfw: limit %d reached on entry %d\n", Modified: head/sys/netpfil/ipfw/ip_fw_nat.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_nat.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw_nat.c Thu Mar 14 22:28:50 2019 (r345162) @@ -347,7 +347,7 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s /* Check if this is 'global' instance */ if (t == NULL) { - if (args->oif == NULL) { + if (args->flags & IPFW_ARGS_IN) { /* Wrong direction, skip processing */ args->m = mcl; return (IP_FW_NAT); @@ -374,7 +374,7 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s return (IP_FW_NAT); } } else { - if (args->oif == NULL) + if (args->flags & IPFW_ARGS_IN) retval = LibAliasIn(t->lib, c, mcl->m_len + M_TRAILINGSPACE(mcl)); else @@ -391,7 +391,8 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, s * PKT_ALIAS_DENY_INCOMING flag is set. */ if (retval == PKT_ALIAS_ERROR || - (args->oif == NULL && (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT || + ((args->flags & IPFW_ARGS_IN) && + (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT || (retval == PKT_ALIAS_IGNORED && (t->mode & PKT_ALIAS_DENY_INCOMING) != 0)))) { /* XXX - should i add some logging? */ Modified: head/sys/netpfil/ipfw/ip_fw_pfil.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_pfil.c Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw_pfil.c Thu Mar 14 22:28:50 2019 (r345162) @@ -118,17 +118,16 @@ SYSEND * The packet may be consumed. */ static pfil_return_t -ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int dir, +ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int flags, void *ruleset __unused, struct inpcb *inp) { struct ip_fw_args args; struct m_tag *tag; pfil_return_t ret; - int ipfw; + int ipfw, dir; - /* convert dir to IPFW values */ - dir = (dir & PFIL_IN) ? DIR_IN : DIR_OUT; - args.flags = 0; + args.flags = (flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT; + dir = (flags & PFIL_IN) ? DIR_IN : DIR_OUT; again: /* * extract and remove the tag if present. If we are left @@ -144,7 +143,7 @@ again: } args.m = *m0; - args.oif = dir == DIR_OUT ? ifp : NULL; + args.ifp = ifp; args.inp = inp; ipfw = ipfw_chk(&args); @@ -198,7 +197,7 @@ again: * m_tag_find. Outgoing packets may be tagged, so we * reuse the tag if present. */ - tag = (dir == DIR_IN) ? NULL : + tag = (flags & PFIL_IN) ? NULL : m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL); if (tag != NULL) { m_tag_unlink(*m0, tag); @@ -346,6 +345,7 @@ ipfw_check_frame(struct mbuf **m0, struct ifnet *ifp, int i; args.flags = IPFW_ARGS_ETHER; + args.flags |= (dir & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT; again: /* fetch start point from rule, if any. remove the tag if present. */ mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); @@ -372,7 +372,7 @@ again: m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */ args.m = m; /* the packet we are looking at */ - args.oif = dir & PFIL_OUT ? ifp: NULL; /* destination, if any */ + args.ifp = ifp; args.eh = &save_eh; /* MAC header for bridged/MAC packets */ args.inp = inp; /* used by ipfw uid/gid/jail rules */ i = ipfw_chk(&args); Modified: head/sys/netpfil/ipfw/ip_fw_private.h ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_private.h Thu Mar 14 22:23:09 2019 (r345161) +++ head/sys/netpfil/ipfw/ip_fw_private.h Thu Mar 14 22:28:50 2019 (r345162) @@ -85,12 +85,19 @@ struct _ip6dn_args { */ struct ip_fw_args { uint32_t flags; -#define IPFW_ARGS_ETHER 0x0001 /* has valid ethernet header */ -#define IPFW_ARGS_NH4 0x0002 /* has IPv4 next hop in hopstore */ -#define IPFW_ARGS_NH6 0x0004 /* has IPv6 next hop in hopstore */ -#define IPFW_ARGS_NH4PTR 0x0008 /* has IPv4 next hop in next_hop */ -#define IPFW_ARGS_NH6PTR 0x0010 /* has IPv6 next hop in next_hop6 */ -#define IPFW_ARGS_REF 0x0020 /* has valid ipfw_rule_ref */ +#define IPFW_ARGS_ETHER 0x00010000 /* valid ethernet header */ +#define IPFW_ARGS_NH4 0x00020000 /* IPv4 next hop in hopstore */ +#define IPFW_ARGS_NH6 0x00040000 /* IPv6 next hop in hopstore */ +#define IPFW_ARGS_NH4PTR 0x00080000 /* IPv4 next hop in next_hop */ +#define IPFW_ARGS_NH6PTR 0x00100000 /* IPv6 next hop in next_hop6 */ +#define IPFW_ARGS_REF 0x00200000 /* valid ipfw_rule_ref */ +#define IPFW_ARGS_IN 0x00400000 /* called on input */ +#define IPFW_ARGS_OUT 0x00800000 /* called on output */ +#define IPFW_ARGS_IP4 0x01000000 /* belongs to v4 ISR */ +#define IPFW_ARGS_IP6 0x02000000 /* belongs to v6 ISR */ +#define IPFW_ARGS_DROP 0x04000000 /* drop it (dummynet) */ +#define IPFW_ARGS_LENMASK 0x0000ffff /* length of data in *mem */ +#define IPFW_ARGS_LENGTH(f) ((f) & IPFW_ARGS_LENMASK) /* * On return, it points to the matching rule. * On entry, rule.slot > 0 means the info is valid and @@ -100,7 +107,7 @@ struct ip_fw_args { */ struct ipfw_rule_ref rule; /* match/restart info */ - struct ifnet *oif; /* output interface */ + struct ifnet *ifp; /* input/output interface */ struct inpcb *inp; union { /* @@ -181,7 +188,7 @@ void ipfw_bpf_init(int); void ipfw_bpf_uninit(int); void ipfw_bpf_mtap2(void *, u_int, struct mbuf *); void ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, - struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif, + struct ip_fw_args *args, struct mbuf *m, u_short offset, uint32_t tablearg, struct ip *ip); VNET_DECLARE(u_int64_t, norule_counter); #define V_norule_counter VNET(norule_counter)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201903142228.x2EMSo2h059922>