From dc0fa4f7122faf346f0a3ca884dabbdbb7467f2d Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 14 Mar 2019 22:32:50 +0000 Subject: [PATCH] Remove 'dir' argument from dummynet_io(). This makes it possible to make dn_dir flags private to dummynet. There is still some room for improvement. --- sys/netinet/ip_var.h | 2 +- sys/netinet/raw_ip.c | 2 +- sys/netpfil/ipfw/ip_dn_io.c | 19 ++++++++++++------- sys/netpfil/ipfw/ip_dn_private.h | 17 ++++++++++++++++- sys/netpfil/ipfw/ip_fw2.c | 2 ++ sys/netpfil/ipfw/ip_fw_pfil.c | 16 ++++++---------- sys/netpfil/ipfw/ip_fw_private.h | 22 ---------------------- 7 files changed, 38 insertions(+), 42 deletions(-) diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 56566e67f842..38602efb3f4e 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -296,7 +296,7 @@ extern void (*ip_divert_ptr)(struct mbuf *m, bool incoming); /* ng_ipfw hooks -- XXX make it the same as divert and dummynet */ extern int (*ng_ipfw_input_p)(struct mbuf **, struct ip_fw_args *, bool); extern int (*ip_dn_ctl_ptr)(struct sockopt *); -extern int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *); +extern int (*ip_dn_io_ptr)(struct mbuf **, struct ip_fw_args *); #endif /* _KERNEL */ #endif /* !_NETINET_IP_VAR_H_ */ diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index c4d218a9d4f3..095cefaa9700 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -100,7 +100,7 @@ VNET_DEFINE(ip_fw_chk_ptr_t, ip_fw_chk_ptr) = NULL; VNET_DEFINE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr) = NULL; int (*ip_dn_ctl_ptr)(struct sockopt *); -int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *); +int (*ip_dn_io_ptr)(struct mbuf **, struct ip_fw_args *); void (*ip_divert_ptr)(struct mbuf *, bool); int (*ng_ipfw_input_p)(struct mbuf **, struct ip_fw_args *, bool); diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c index 25e469f022bb..0bd869076779 100644 --- a/sys/netpfil/ipfw/ip_dn_io.c +++ b/sys/netpfil/ipfw/ip_dn_io.c @@ -854,22 +854,27 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa) * We use the argument to locate the flowset fs and the sched_set sch * associated to it. The we apply flow_mask and sched_mask to * determine the queue and scheduler instances. - * - * dir where shall we send the packet after dummynet. - * *m0 the mbuf with the packet - * ifp the 'ifp' parameter from the caller. - * NULL in ip_input, destination interface in ip_output, */ int -dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) +dummynet_io(struct mbuf **m0, struct ip_fw_args *fwa) { struct mbuf *m = *m0; struct dn_fsk *fs = NULL; struct dn_sch_inst *si; struct dn_queue *q = NULL; /* default */ + int fs_id, dir; - int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + + fs_id = (fwa->rule.info & IPFW_INFO_MASK) + ((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0); + /* XXXGL: convert args to dir */ + if (fwa->flags & IPFW_ARGS_IN) + dir = DIR_IN; + else + dir = DIR_OUT; + if (fwa->flags & IPFW_ARGS_ETHER) + dir |= PROTO_LAYER2; + else if (fwa->flags & IPFW_ARGS_IP6) + dir |= PROTO_IPV6; DN_BH_WLOCK(); io_pkt++; /* we could actually tag outside the lock, but who cares... */ diff --git a/sys/netpfil/ipfw/ip_dn_private.h b/sys/netpfil/ipfw/ip_dn_private.h index 61c61130525c..5f564ef68c86 100644 --- a/sys/netpfil/ipfw/ip_dn_private.h +++ b/sys/netpfil/ipfw/ip_dn_private.h @@ -387,11 +387,26 @@ struct dn_pkt_tag { uint16_t iphdr_off; /* IP header offset for mtodo() */ }; +/* + * Possible values for dn_dir. XXXGL: this needs to be reviewed + * and converted to same values ip_fw_args.flags use. + */ +enum { + DIR_OUT = 0, + DIR_IN = 1, + DIR_FWD = 2, + DIR_DROP = 3, + PROTO_LAYER2 = 0x4, /* set for layer 2 */ + PROTO_IPV4 = 0x08, + PROTO_IPV6 = 0x10, + PROTO_IFB = 0x0c, /* layer2 + ifbridge */ +}; + extern struct dn_parms dn_cfg; //VNET_DECLARE(struct dn_parms, _base_dn_cfg); //#define dn_cfg VNET(_base_dn_cfg) -int dummynet_io(struct mbuf **, int , struct ip_fw_args *); +int dummynet_io(struct mbuf **, struct ip_fw_args *); void dummynet_task(void *context, int pending); void dn_reschedule(void); struct dn_pkt_tag * dn_tag_get(struct mbuf *m); diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index 1d9fc2e15733..f00d58ea02a2 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -1436,6 +1436,7 @@ do { \ struct ip6_hdr *ip6 = (struct ip6_hdr *)ip; is_ipv6 = 1; + args->flags |= IPFW_ARGS_IP6; hlen = sizeof(struct ip6_hdr); proto = ip6->ip6_nxt; /* Search extension headers to find upper layer protocols */ @@ -1618,6 +1619,7 @@ do { \ } else if (pktlen >= sizeof(struct ip) && (etype == 0 || etype == ETHERTYPE_IP) && ip->ip_v == 4) { is_ipv4 = 1; + args->flags |= IPFW_ARGS_IP4; hlen = ip->ip_hl << 2; /* * Collect parameters into local variables for faster diff --git a/sys/netpfil/ipfw/ip_fw_pfil.c b/sys/netpfil/ipfw/ip_fw_pfil.c index aad80538810b..e5fccb12fd01 100644 --- a/sys/netpfil/ipfw/ip_fw_pfil.c +++ b/sys/netpfil/ipfw/ip_fw_pfil.c @@ -124,10 +124,9 @@ ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int flags, struct ip_fw_args args; struct m_tag *tag; pfil_return_t ret; - int ipfw, dir; + int ipfw; 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 @@ -254,10 +253,8 @@ again: break; } MPASS(args.flags & IPFW_ARGS_REF); - if (mtod(*m0, struct ip *)->ip_v == 4) - (void )ip_dn_io_ptr(m0, dir, &args); - else if (mtod(*m0, struct ip *)->ip_v == 6) - (void )ip_dn_io_ptr(m0, dir | PROTO_IPV6, &args); + if (args.flags & (IPFW_ARGS_IP4 | IPFW_ARGS_IP6)) + (void )ip_dn_io_ptr(m0, &args); else { ret = PFIL_DROPPED; break; @@ -331,7 +328,7 @@ again: * ipfw processing for ethernet packets (in and out). */ static pfil_return_t -ipfw_check_frame(struct mbuf **m0, struct ifnet *ifp, int dir, +ipfw_check_frame(struct mbuf **m0, struct ifnet *ifp, int flags, void *ruleset __unused, struct inpcb *inp) { struct ip_fw_args args; @@ -343,7 +340,7 @@ ipfw_check_frame(struct mbuf **m0, struct ifnet *ifp, int dir, int i; args.flags = IPFW_ARGS_ETHER; - args.flags |= (dir & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT; + args.flags |= (flags & 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); @@ -407,9 +404,8 @@ again: break; } *m0 = NULL; - dir = (dir & PFIL_IN) ? DIR_IN : DIR_OUT; MPASS(args.flags & IPFW_ARGS_REF); - ip_dn_io_ptr(&m, dir | PROTO_LAYER2, &args); + ip_dn_io_ptr(&m, &args); return (PFIL_CONSUMED); case IP_FW_NGTEE: diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h index 4d5b63fc8214..978dbe6ab703 100644 --- a/sys/netpfil/ipfw/ip_fw_private.h +++ b/sys/netpfil/ipfw/ip_fw_private.h @@ -136,28 +136,6 @@ struct ip_fw_args { MALLOC_DECLARE(M_IPFW); -/* - * Hooks sometime need to know the direction of the packet - * (divert, dummynet, netgraph, ...) - * We use a generic definition here, with bit0-1 indicating the - * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the - * specific protocol - * indicating the protocol (if necessary) - */ -enum { - DIR_MASK = 0x3, - DIR_OUT = 0, - DIR_IN = 1, - DIR_FWD = 2, - DIR_DROP = 3, - PROTO_LAYER2 = 0x4, /* set for layer 2 */ - /* PROTO_DEFAULT = 0, */ - PROTO_IPV4 = 0x08, - PROTO_IPV6 = 0x10, - PROTO_IFB = 0x0c, /* layer2 + ifbridge */ - /* PROTO_OLDBDG = 0x14, unused, old bridge */ -}; - /* wrapper for freeing a packet, in case we need to do more work */ #ifndef FREE_PKT #if defined(__linux__) || defined(_WIN32)