Date: Sat, 7 Jun 2014 12:55:25 GMT From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r269232 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw Message-ID: <201406071255.s57CtPWS012716@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dpl Date: Sat Jun 7 12:55:25 2014 New Revision: 269232 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269232 Log: Finished with the function headers. Now I'm going to add the code to ip_rules.c and the types to ip_rules.h. Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c ============================================================================== --- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c Sat Jun 7 10:13:45 2014 (r269231) +++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c Sat Jun 7 12:55:25 2014 (r269232) @@ -17,11 +17,7 @@ } inline void -#ifndef __FreeBSD__ //XXX Clean this up if needed. -rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, struct ip_fw_args *args, int ucred_lookup, struct bsd_ucred *ucred_cache) -#else -rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, struct ip_fw_args *args, int ucred_lookup, struct ucred *ucred_cache) -#endif +rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, struct ip_fw_args *args, int ucred_lookup, void *ucred_cache) { /* * We only check offset == 0 && proto != 0, @@ -36,8 +32,95 @@ (ipfw_insn_u32 *)cmd, args, &ucred_lookup, #ifdef __FreeBSD__ - &ucred_cache); + &(struct bsd_ucred *)ucred_cache); #else - (void *)&ucred_cache); + (void *)&(struct ucred *)ucred_cache); #endif } + +inline void rule_recv(int *int *int *int *match, m, cmd, chain, tablearg); +inline void rule_xmit(int *match, oif, cmd, chain, tablearg); +inline void rule_via(int *match, oif, rcvif, cmd, chain, tablearg); +inline void rule_macaddr(int *match, eh, adr, mask, eh); +inline void rule_mac_type(int *match, eh, ports, cmdlen, etype)); +inline void rule_frag(int *match, offset); +inline void rule_in(int *match, oif); +inline void rule_layertwo(int *match, eh); +inline void rule_diverted(int *match, info); +inline void rule_proto(int *match, proto, arg1); +inline void rule_ip_src(int *match, is_ipv4, addr1, addr2); +inline void rule_ip_2_lookup(int *match, cmd, cmdlen, is_ipv4, is_ipv6, ip, dst_ip, + src_ip, dst_port, src_port, offset, proto, ucred_lookup, ucred_cache, key, chain); +inline void rule_ip_dst_mask(int *match, is_ipv4, cmd, dst_ip); +inline void rule_ip_src_me(int *match, src_ip, args); +inline void rule_ip_src_set(int *match, is_ipv4, cmd, args) +inline void rule_ip_dst(int *match, is_ipv4, cmd, addr1, addr2); +inline void rule_ip_dst_me(int *match, is_ipv4, is_ipv6, dst_ip, dst_ip6); +inline void rule_ip_dstport(int *match, proto, opcode, ports, cmdlen); +inline void rule_icmptype(int *match, offset, proto,ulp, cmd ); +inline void rule_ipopt(int *match, is_ipv4, ip, cmd); +inline void rule_ipver(int *match, is_ipv4, arg1, ip_v); +inline void rule_ipttl(int *match, is_ipv4, opcode, iplen, ip_ttl, ip_id, cmdlen, ports); +inline void rule_ipprecedence(int *match, is_ipv4, arg1, ip_tos); +inline void rule_iptos(int *match, is_ipv4, cmd, ip_tos) +inline void rule_dscp(d, is_ipv4, ip_tos, is_ipv6, ip6_vfc); +inline void rule_tcpdatalen(int *match, proto, offset, ulp, iplen, cmdlen, arg1, ports); +inline void rule_tcpflags(int *match, proto, offset, cmd, th_flags); +inline void rule_tcpopts(int *match, hlen, ulp, th_off, proto, offset, cmd); +inline void rule_tcpseq(int *match, proto, offset, cmd, ulp); +inline void rule_tcpack(int *match, proto, offset, cmd, ulp); +inline void rule_tcpwin(int *match, proto, offset, cmd, ulp); +inline void rule_estab(int *match, proto, offset, ulp); +inline void rule_altq(int *match, cmd, m, tag /*PACKET_TAG_PF*/, size_t size, num); +inline void rule_log(int *match, f, hlen, args, m, oif, offset, ip6f_mf, tablearg, ip); +inline void rule_prob(int *match, cmd); +inline void rule_verrevpath(int *match, oif, m, is_ipv6, args, src_ip); +inline void rule_versrcreach(int *match, is_ipv6, args, src_ip); +inline void rule_antispoof(int *match, oif, hlen, is_ipv4, src_ip, is_ipv6, args, m); +inline void rule_ip4(int *match, is_ipv4); +inline void rule_tag(int *match, cmd, m, tag, ); +inline void rule_fib(int *match, args, cmd); +inline void rule_tagged(int *match, cmd, cmdlen, m, ipfw, tag); + +#ifdef INET6 +inline void rule_icmp6type(int *match, offset, proto, icmp6_type, cmd); +inline void rule_ip6_src(int *match, is_ipv6, src_ip6, addr6); +inline void rule_ip6_dst(int *match, is_ipv6, dst_ip6, addr6); +inline void rule_ip6_dst_mask(int *match, args, cmd, cmdlen, is_ipv6, dst_ip6, addr6); +inline void rule_ip6_dst(int *match, is_ipv6, flow_id6, cmd); +inline void rule_is_ipv6(int *match, is_ipv6, ext_hd, cmd); +inline void rule_ip6(int *match, is_ipv6); +#endif + +#ifdef IPSEC +inline void rule_ipsec(int *match, m); +endif + +#ifndef USERSPACE /* not supported in userspace */ +inline void rule_sockarg(int *match, is_ipv6, proto, args, tcbinfo, udbinfo, inp, scr_ip, src_port, dst_ip, dst_port, tablearg); +#endif /* !USERSPACE */ + +/* + * The second round of actions. + */ +inline void rule_keep_state(int *match, f, cmd, args, tableargs, retval, l, done); +inline void rule_check_state(int *match, dyn_dir, q, args, proto, ulp, pktlen, f, f_pos, chain, cmd, cmdlen, l); +inline void rule_accept(retval, l, done); +inline void rule_queue(args, f_pos, chain, cmd, retval, l, done); +inline void rule_tee(args, l, done, retval, cmd, args, f_pos, chain); +inline void rule_count(l, f, pktlen); +inline void rule_skipto(int *match, f, f_pos, pktlen, chain, cmd, tablearg, f, l, cmd, cmdlen, skip_or); +inline void rule_callreturn(cmd, cmdlen, m, l, f, pktlen, tablearg, jmpto, f_pos, chain, skip_or); +inline void rule_reject(hlen, is_ipv4, offset, proto, ulp, m, dst_ip, args, cmd, iplen, ip); +inline void rule_deny(l, done, retval); +inline void rule_forward_ip(args, q, dyn_dir, cmd, sa, retval, l, done); +inline void rule_ngtee(args, f_pos, chain, cmd, V_fw_one_pass, retval, l, done); +inline void rule_setfib(f, pktlen, cmd, rt_numfibs, m, args, l); +inline void rule_setdscp(cmd, l, is_ipv4, a, is_ipv6, f, pktlen); +inline void rule_nat(l, done, retval, args, f_pos, chain, cmd, chain); +inlinue void rule_reass(f, pktlen, l, ip_off, ip, args, m, retval, done); + +#ifdef INET6 +inline void rule_unreach6(hlen, is_ipv4, offset, proto, icmp6_type, m, args, cmd, ip); +inline void rule_forward_ip6(args, q, f, dun_dir, cmd, args, retval, l, done); +#endif Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h ============================================================================== --- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h Sat Jun 7 10:13:45 2014 (r269231) +++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h Sat Jun 7 12:55:25 2014 (r269232) @@ -1,1185 +1,96 @@ /* * The header containing the functions corresponding to each rule. + * XXX - Still have to add the type to the args. */ - inline void rule_nop(int *match); inline void rule_forward_mac(int opcode); -#ifndef __FreeBSD__ //XXX Clean this up if needed. -inline void rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, - struct ip_fw_args *args, int ucred_lookup, struct bsd_ucred *ucred_cache) -#else inline void rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, - struct ip_fw_args *args, int ucred_lookup, struct ucred *ucred_cache) -#endif - -/* - case O_RECV: //RULEFUNC= rule_recv(match) - match = iface_match(m->m_pkthdr.rcvif, - (ipfw_insn_if *)cmd, chain, &tablearg); - break; - - case O_XMIT: - match = iface_match(oif, (ipfw_insn_if *)cmd, - chain, &tablearg); - break; - - case O_VIA: - match = iface_match(oif ? oif : - m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, - chain, &tablearg); - break; - - case O_MACADDR2: //RULEFUNC = rule_macaddr2() - if (args->eh != NULL) { /* have MAC header */ - u_int32_t *want = (u_int32_t *) - ((ipfw_insn_mac *)cmd)->addr; - u_int32_t *mask = (u_int32_t *) - ((ipfw_insn_mac *)cmd)->mask; - u_int32_t *hdr = (u_int32_t *)args->eh; - - match = - ( want[0] == (hdr[0] & mask[0]) && - want[1] == (hdr[1] & mask[1]) && - want[2] == (hdr[2] & mask[2]) ); - } - break; - - case O_MAC_TYPE: - if (args->eh != NULL) { - u_int16_t *p = - ((ipfw_insn_u16 *)cmd)->ports; - int i; - - for (i = cmdlen - 1; !match && i>0; - i--, p += 2) - match = (etype >= p[0] && - etype <= p[1]); - } - break; - - case O_FRAG: - match = (offset != 0); - break; - - case O_IN: /* "out" is "not in" */ - match = (oif == NULL); - break; - - case O_LAYER2: - match = (args->eh != NULL); - break; - - case O_DIVERTED: - { - /* For diverted packets, args->rule.info - * contains the divert port (in host format) - * reason and direction. - */ - uint32_t i = args->rule.info; - match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT && - cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2); - } - break; - - case O_PROTO: - /* - * We do not allow an arg of 0 so the - * check of "proto" only suffices. - */ - match = (proto == cmd->arg1); - break; - - case O_IP_SRC: - match = is_ipv4 && - (((ipfw_insn_ip *)cmd)->addr.s_addr == - src_ip.s_addr); - break; - - case O_IP_SRC_LOOKUP: - case O_IP_DST_LOOKUP: - if (is_ipv4) { - uint32_t key = - (cmd->opcode == O_IP_DST_LOOKUP) ? - dst_ip.s_addr : src_ip.s_addr; - uint32_t v = 0; - - if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { - /* generic lookup. The key must be - * in 32bit big-endian format. - */ - v = ((ipfw_insn_u32 *)cmd)->d[1]; - if (v == 0) - key = dst_ip.s_addr; - else if (v == 1) - key = src_ip.s_addr; - else if (v == 6) /* dscp */ - key = (ip->ip_tos >> 2) & 0x3f; - else if (offset != 0) - break; - else if (proto != IPPROTO_TCP && - proto != IPPROTO_UDP) - break; - else if (v == 2) - key = htonl(dst_port); - else if (v == 3) - key = htonl(src_port); -#ifndef USERSPACE - else if (v == 4 || v == 5) { - check_uidgid( - (ipfw_insn_u32 *)cmd, - args, &ucred_lookup, -#ifdef __FreeBSD__ - &ucred_cache); - if (v == 4 /* O_UID */) - key = ucred_cache->cr_uid; - else if (v == 5 /* O_JAIL */) - key = ucred_cache->cr_prison->pr_id; -#else /* !__FreeBSD__ */ - (void *)&ucred_cache); - if (v ==4 /* O_UID */) - key = ucred_cache.uid; - else if (v == 5 /* O_JAIL */) - key = ucred_cache.xid; -#endif /* !__FreeBSD__ */ - key = htonl(key); - } else -#endif /* !USERSPACE */ - break; - } - match = ipfw_lookup_table(chain, - cmd->arg1, key, &v); - if (!match) - break; - if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) - match = - ((ipfw_insn_u32 *)cmd)->d[0] == v; - else - tablearg = v; - } else if (is_ipv6) { - uint32_t v = 0; - void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ? - &args->f_id.dst_ip6: &args->f_id.src_ip6; - match = ipfw_lookup_table_extended(chain, - cmd->arg1, pkey, &v, - IPFW_TABLE_CIDR); - if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) - match = ((ipfw_insn_u32 *)cmd)->d[0] == v; - if (match) - tablearg = v; - } - break; - - case O_IP_SRC_MASK: - case O_IP_DST_MASK: - if (is_ipv4) { - uint32_t a = - (cmd->opcode == O_IP_DST_MASK) ? - dst_ip.s_addr : src_ip.s_addr; - uint32_t *p = ((ipfw_insn_u32 *)cmd)->d; - int i = cmdlen-1; - - for (; !match && i>0; i-= 2, p+= 2) - match = (p[0] == (a & p[1])); - } - break; - - case O_IP_SRC_ME: - if (is_ipv4) { - struct ifnet *tif; - - INADDR_TO_IFP(src_ip, tif); - match = (tif != NULL); - break; - } -#ifdef INET6 - /* FALLTHROUGH */ - case O_IP6_SRC_ME: - match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6); -#endif - break; - - case O_IP_DST_SET: - case O_IP_SRC_SET: - if (is_ipv4) { - u_int32_t *d = (u_int32_t *)(cmd+1); - u_int32_t addr = - cmd->opcode == O_IP_DST_SET ? - args->f_id.dst_ip : - args->f_id.src_ip; - - if (addr < d[0]) - break; - addr -= d[0]; /* subtract base */ - match = (addr < cmd->arg1) && - ( d[ 1 + (addr>>5)] & - (1<<(addr & 0x1f)) ); - } - break; - - case O_IP_DST: - match = is_ipv4 && - (((ipfw_insn_ip *)cmd)->addr.s_addr == - dst_ip.s_addr); - break; - - case O_IP_DST_ME: - if (is_ipv4) { - struct ifnet *tif; - - INADDR_TO_IFP(dst_ip, tif); - match = (tif != NULL); - break; - } -#ifdef INET6 - /* FALLTHROUGH */ - case O_IP6_DST_ME: - match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6); -#endif - break; - - - case O_IP_SRCPORT: - case O_IP_DSTPORT: - /* - * offset == 0 && proto != 0 is enough - * to guarantee that we have a - * packet with port info. - */ - if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP) - && offset == 0) { - u_int16_t x = - (cmd->opcode == O_IP_SRCPORT) ? - src_port : dst_port ; - u_int16_t *p = - ((ipfw_insn_u16 *)cmd)->ports; - int i; - - for (i = cmdlen - 1; !match && i>0; - i--, p += 2) - match = (x>=p[0] && x<=p[1]); - } - break; + struct ip_fw_args *args, int ucred_lookup, void *ucred_cache) - case O_ICMPTYPE: - match = (offset == 0 && proto==IPPROTO_ICMP && - icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) ); - break; - -#ifdef INET6 - case O_ICMP6TYPE: - match = is_ipv6 && offset == 0 && - proto==IPPROTO_ICMPV6 && - icmp6type_match( - ICMP6(ulp)->icmp6_type, - (ipfw_insn_u32 *)cmd); - break; -#endif /* INET6 */ - - case O_IPOPT: - match = (is_ipv4 && - ipopts_match(ip, cmd) ); - break; - - case O_IPVER: - match = (is_ipv4 && - cmd->arg1 == ip->ip_v); - break; - - case O_IPID: - case O_IPLEN: - case O_IPTTL: - if (is_ipv4) { /* only for IP packets */ - uint16_t x; - uint16_t *p; - int i; - - if (cmd->opcode == O_IPLEN) - x = iplen; - else if (cmd->opcode == O_IPTTL) - x = ip->ip_ttl; - else /* must be IPID */ - x = ntohs(ip->ip_id); - if (cmdlen == 1) { - match = (cmd->arg1 == x); - break; - } - /* otherwise we have ranges */ - p = ((ipfw_insn_u16 *)cmd)->ports; - i = cmdlen - 1; - for (; !match && i>0; i--, p += 2) - match = (x >= p[0] && x <= p[1]); - } - break; - - case O_IPPRECEDENCE: - match = (is_ipv4 && - (cmd->arg1 == (ip->ip_tos & 0xe0)) ); - break; - - case O_IPTOS: - match = (is_ipv4 && - flags_match(cmd, ip->ip_tos)); - break; - - case O_DSCP: - { - uint32_t *p; - uint16_t x; - - p = ((ipfw_insn_u32 *)cmd)->d; - - if (is_ipv4) - x = ip->ip_tos >> 2; - else if (is_ipv6) { - uint8_t *v; - v = &((struct ip6_hdr *)ip)->ip6_vfc; - x = (*v & 0x0F) << 2; - v++; - x |= *v >> 6; - } else - break; - - /* DSCP bitmask is stored as low_u32 high_u32 */ - if (x > 32) - match = *(p + 1) & (1 << (x - 32)); - else - match = *p & (1 << x); - } - break; - - case O_TCPDATALEN: - if (proto == IPPROTO_TCP && offset == 0) { - struct tcphdr *tcp; - uint16_t x; - uint16_t *p; - int i; - - tcp = TCP(ulp); - x = iplen - - ((ip->ip_hl + tcp->th_off) << 2); - if (cmdlen == 1) { - match = (cmd->arg1 == x); - break; - } - /* otherwise we have ranges */ - p = ((ipfw_insn_u16 *)cmd)->ports; - i = cmdlen - 1; - for (; !match && i>0; i--, p += 2) - match = (x >= p[0] && x <= p[1]); - } - break; - - case O_TCPFLAGS: - match = (proto == IPPROTO_TCP && offset == 0 && - flags_match(cmd, TCP(ulp)->th_flags)); - break; - - case O_TCPOPTS: - PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2)); - match = (proto == IPPROTO_TCP && offset == 0 && - tcpopts_match(TCP(ulp), cmd)); - break; - - case O_TCPSEQ: - match = (proto == IPPROTO_TCP && offset == 0 && - ((ipfw_insn_u32 *)cmd)->d[0] == - TCP(ulp)->th_seq); - break; - - case O_TCPACK: - match = (proto == IPPROTO_TCP && offset == 0 && - ((ipfw_insn_u32 *)cmd)->d[0] == - TCP(ulp)->th_ack); - break; - - case O_TCPWIN: - if (proto == IPPROTO_TCP && offset == 0) { - uint16_t x; - uint16_t *p; - int i; - - x = ntohs(TCP(ulp)->th_win); - if (cmdlen == 1) { - match = (cmd->arg1 == x); - break; - } - /* Otherwise we have ranges. */ - p = ((ipfw_insn_u16 *)cmd)->ports; - i = cmdlen - 1; - for (; !match && i > 0; i--, p += 2) - match = (x >= p[0] && x <= p[1]); - } - break; - - case O_ESTAB: - /* reject packets which have SYN only */ - /* XXX should i also check for TH_ACK ? */ - match = (proto == IPPROTO_TCP && offset == 0 && - (TCP(ulp)->th_flags & - (TH_RST | TH_ACK | TH_SYN)) != TH_SYN); - break; - - case O_ALTQ: { - struct pf_mtag *at; - struct m_tag *mtag; - ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; - - /* - * ALTQ uses mbuf tags from another - * packet filtering system - pf(4). - * We allocate a tag in its format - * and fill it in, pretending to be pf(4). - */ - match = 1; - at = pf_find_mtag(m); - if (at != NULL && at->qid != 0) - break; - mtag = m_tag_get(PACKET_TAG_PF, - sizeof(struct pf_mtag), M_NOWAIT | M_ZERO); - if (mtag == NULL) { - /* - * Let the packet fall back to the - * default ALTQ. - */ - break; - } - m_tag_prepend(m, mtag); - at = (struct pf_mtag *)(mtag + 1); - at->qid = altq->qid; - at->hdr = ip; - break; - } - - case O_LOG: - ipfw_log(f, hlen, args, m, - oif, offset | ip6f_mf, tablearg, ip); - match = 1; - break; - - case O_PROB: - match = (random()<((ipfw_insn_u32 *)cmd)->d[0]); - break; - - case O_VERREVPATH: - /* Outgoing packets automatically pass/match */ - match = ((oif != NULL) || - (m->m_pkthdr.rcvif == NULL) || - ( -#ifdef INET6 - is_ipv6 ? - verify_path6(&(args->f_id.src_ip6), - m->m_pkthdr.rcvif, args->f_id.fib) : -#endif - verify_path(src_ip, m->m_pkthdr.rcvif, - args->f_id.fib))); - break; - - case O_VERSRCREACH: - /* Outgoing packets automatically pass/match */ - match = (hlen > 0 && ((oif != NULL) || -#ifdef INET6 - is_ipv6 ? - verify_path6(&(args->f_id.src_ip6), - NULL, args->f_id.fib) : -#endif - verify_path(src_ip, NULL, args->f_id.fib))); - break; - - case O_ANTISPOOF: - /* Outgoing packets automatically pass/match */ - if (oif == NULL && hlen > 0 && - ( (is_ipv4 && in_localaddr(src_ip)) -#ifdef INET6 - || (is_ipv6 && - in6_localaddr(&(args->f_id.src_ip6))) -#endif - )) - match = -#ifdef INET6 - is_ipv6 ? verify_path6( - &(args->f_id.src_ip6), - m->m_pkthdr.rcvif, - args->f_id.fib) : +inline void rule_recv(int *int *int *int *match, m, cmd, chain, tablearg); +inline void rule_xmit(int *match, oif, cmd, chain, tablearg); +inline void rule_via(int *match, oif, rcvif, cmd, chain, tablearg); +inline void rule_macaddr(int *match, eh, adr, mask, eh); +inline void rule_mac_type(int *match, eh, ports, cmdlen, etype)); +inline void rule_frag(int *match, offset); +inline void rule_in(int *match, oif); +inline void rule_layertwo(int *match, eh); +inline void rule_diverted(int *match, info); +inline void rule_proto(int *match, proto, arg1); +inline void rule_ip_src(int *match, is_ipv4, addr1, addr2); +inline void rule_ip_2_lookup(int *match, cmd, cmdlen, is_ipv4, is_ipv6, ip, dst_ip, + src_ip, dst_port, src_port, offset, proto, ucred_lookup, ucred_cache, key, chain); +inline void rule_ip_dst_mask(int *match, is_ipv4, cmd, dst_ip); +inline void rule_ip_src_me(int *match, src_ip, args); +inline void rule_ip_src_set(int *match, is_ipv4, cmd, args) +inline void rule_ip_dst(int *match, is_ipv4, cmd, addr1, addr2); +inline void rule_ip_dst_me(int *match, is_ipv4, is_ipv6, dst_ip, dst_ip6); +inline void rule_ip_dstport(int *match, proto, opcode, ports, cmdlen); +inline void rule_icmptype(int *match, offset, proto,ulp, cmd ); +inline void rule_ipopt(int *match, is_ipv4, ip, cmd); +inline void rule_ipver(int *match, is_ipv4, arg1, ip_v); +inline void rule_ipttl(int *match, is_ipv4, opcode, iplen, ip_ttl, ip_id, cmdlen, ports); +inline void rule_ipprecedence(int *match, is_ipv4, arg1, ip_tos); +inline void rule_iptos(int *match, is_ipv4, cmd, ip_tos) +inline void rule_dscp(d, is_ipv4, ip_tos, is_ipv6, ip6_vfc); +inline void rule_tcpdatalen(int *match, proto, offset, ulp, iplen, cmdlen, arg1, ports); +inline void rule_tcpflags(int *match, proto, offset, cmd, th_flags); +inline void rule_tcpopts(int *match, hlen, ulp, th_off, proto, offset, cmd); +inline void rule_tcpseq(int *match, proto, offset, cmd, ulp); +inline void rule_tcpack(int *match, proto, offset, cmd, ulp); +inline void rule_tcpwin(int *match, proto, offset, cmd, ulp); +inline void rule_estab(int *match, proto, offset, ulp); +inline void rule_altq(int *match, cmd, m, tag /*PACKET_TAG_PF*/, size_t size, num); +inline void rule_log(int *match, f, hlen, args, m, oif, offset, ip6f_mf, tablearg, ip); +inline void rule_prob(int *match, cmd); +inline void rule_verrevpath(int *match, oif, m, is_ipv6, args, src_ip); +inline void rule_versrcreach(int *match, is_ipv6, args, src_ip); +inline void rule_antispoof(int *match, oif, hlen, is_ipv4, src_ip, is_ipv6, args, m); +inline void rule_ip4(int *match, is_ipv4); +inline void rule_tag(int *match, cmd, m, tag, ); +inline void rule_fib(int *match, args, cmd); +inline void rule_tagged(int *match, cmd, cmdlen, m, ipfw, tag); + +#ifdef INET6 +inline void rule_icmp6type(int *match, offset, proto, icmp6_type, cmd); +inline void rule_ip6_src(int *match, is_ipv6, src_ip6, addr6); +inline void rule_ip6_dst(int *match, is_ipv6, dst_ip6, addr6); +inline void rule_ip6_dst_mask(int *match, args, cmd, cmdlen, is_ipv6, dst_ip6, addr6); +inline void rule_ip6_dst(int *match, is_ipv6, flow_id6, cmd); +inline void rule_is_ipv6(int *match, is_ipv6, ext_hd, cmd); +inline void rule_ip6(int *match, is_ipv6); #endif - verify_path(src_ip, - m->m_pkthdr.rcvif, - args->f_id.fib); - else - match = 1; - break; - case O_IPSEC: #ifdef IPSEC - match = (m_tag_find(m, - PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL); -#endif - /* otherwise no match */ - break; - -#ifdef INET6 - case O_IP6_SRC: - match = is_ipv6 && - IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6, - &((ipfw_insn_ip6 *)cmd)->addr6); - break; - - case O_IP6_DST: - match = is_ipv6 && - IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6, - &((ipfw_insn_ip6 *)cmd)->addr6); - break; - case O_IP6_SRC_MASK: - case O_IP6_DST_MASK: - if (is_ipv6) { - int i = cmdlen - 1; - struct in6_addr p; - struct in6_addr *d = - &((ipfw_insn_ip6 *)cmd)->addr6; - - for (; !match && i > 0; d += 2, - i -= F_INSN_SIZE(struct in6_addr) - * 2) { - p = (cmd->opcode == - O_IP6_SRC_MASK) ? - args->f_id.src_ip6: - args->f_id.dst_ip6; - APPLY_MASK(&p, &d[1]); - match = - IN6_ARE_ADDR_EQUAL(&d[0], - &p); - } - } - break; - - case O_FLOW6ID: - match = is_ipv6 && - flow6id_match(args->f_id.flow_id6, - (ipfw_insn_u32 *) cmd); - break; - - case O_EXT_HDR: - match = is_ipv6 && - (ext_hd & ((ipfw_insn *) cmd)->arg1); - break; - - case O_IP6: - match = is_ipv6; - break; -#endif - - case O_IP4: - match = is_ipv4; - break; - - case O_TAG: { - struct m_tag *mtag; - uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1); - - /* Packet is already tagged with this tag? */ - mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL); - - /* We have `untag' action when F_NOT flag is - * present. And we must remove this mtag from - * mbuf and reset `match' to zero (`match' will - * be inversed later). - * Otherwise we should allocate new mtag and - * push it into mbuf. - */ - if (cmd->len & F_NOT) { /* `untag' action */ - if (mtag != NULL) - m_tag_delete(m, mtag); - match = 0; - } else { - if (mtag == NULL) { - mtag = m_tag_alloc( MTAG_IPFW, - tag, 0, M_NOWAIT); - if (mtag != NULL) - m_tag_prepend(m, mtag); - } - match = 1; - } - break; - } +inline void rule_ipsec(int *match, m); +endif - case O_FIB: /* try match the specified fib */ - if (args->f_id.fib == cmd->arg1) - match = 1; - break; - - case O_SOCKARG: { #ifndef USERSPACE /* not supported in userspace */ - struct inpcb *inp = args->inp; - struct inpcbinfo *pi; - - if (is_ipv6) /* XXX can we remove this ? */ - break; - - if (proto == IPPROTO_TCP) - pi = &V_tcbinfo; - else if (proto == IPPROTO_UDP) - pi = &V_udbinfo; - else - break; - - /* - * XXXRW: so_user_cookie should almost - * certainly be inp_user_cookie? - */ - - /* For incomming packet, lookup up the - inpcb using the src/dest ip/port tuple */ - if (inp == NULL) { - inp = in_pcblookup(pi, - src_ip, htons(src_port), - dst_ip, htons(dst_port), - INPLOOKUP_RLOCKPCB, NULL); - if (inp != NULL) { - tablearg = - inp->inp_socket->so_user_cookie; - if (tablearg) - match = 1; - INP_RUNLOCK(inp); - } - } else { - if (inp->inp_socket) { - tablearg = - inp->inp_socket->so_user_cookie; - if (tablearg) - match = 1; - } - } -#endif /* !USERSPACE */ - break; - } - - case O_TAGGED: { - struct m_tag *mtag; - uint32_t tag = IP_FW_ARG_TABLEARG(cmd->arg1); - - if (cmdlen == 1) { - match = m_tag_locate(m, MTAG_IPFW, - tag, NULL) != NULL; - break; - } - - /* we have ranges */ - for (mtag = m_tag_first(m); - mtag != NULL && !match; - mtag = m_tag_next(m, mtag)) { - uint16_t *p; - int i; - - if (mtag->m_tag_cookie != MTAG_IPFW) - continue; - - p = ((ipfw_insn_u16 *)cmd)->ports; - i = cmdlen - 1; - for(; !match && i > 0; i--, p += 2) - match = - mtag->m_tag_id >= p[0] && - mtag->m_tag_id <= p[1]; - } - break; - } - - /* - * The second set of opcodes represents 'actions', - * i.e. the terminal part of a rule once the packet - * matches all previous patterns. - * Typically there is only one action for each rule, - * and the opcode is stored at the end of the rule - * (but there are exceptions -- see below). - * - * In general, here we set retval and terminate the - * outer loop (would be a 'break 3' in some language, - * but we need to set l=0, done=1) - * - * Exceptions: - * O_COUNT and O_SKIPTO actions: - * instead of terminating, we jump to the next rule - * (setting l=0), or to the SKIPTO target (setting - * f/f_len, cmd and l as needed), respectively. - * - * O_TAG, O_LOG and O_ALTQ action parameters: - * perform some action and set match = 1; - * - * O_LIMIT and O_KEEP_STATE: these opcodes are - * not real 'actions', and are stored right - * before the 'action' part of the rule. - * These opcodes try to install an entry in the - * state tables; if successful, we continue with - * the next opcode (match=1; break;), otherwise - * the packet must be dropped (set retval, - * break loops with l=0, done=1) - * - * O_PROBE_STATE and O_CHECK_STATE: these opcodes - * cause a lookup of the state table, and a jump - * to the 'action' part of the parent rule - * if an entry is found, or - * (CHECK_STATE only) a jump to the next rule if - * the entry is not found. - * The result of the lookup is cached so that - * further instances of these opcodes become NOPs. - * The jump to the next rule is done by setting - * l=0, cmdlen=0. - */ - case O_LIMIT: - case O_KEEP_STATE: - if (ipfw_install_state(f, - (ipfw_insn_limit *)cmd, args, tablearg)) { - /* error or limit violation */ - retval = IP_FW_DENY; - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ - } - match = 1; - break; - - case O_PROBE_STATE: - case O_CHECK_STATE: - /* - * dynamic rules are checked at the first - * keep-state or check-state occurrence, - * with the result being stored in dyn_dir. - * The compiler introduces a PROBE_STATE - * instruction for us when we have a - * KEEP_STATE (because PROBE_STATE needs - * to be run first). - */ - if (dyn_dir == MATCH_UNKNOWN && - (q = ipfw_lookup_dyn_rule(&args->f_id, - &dyn_dir, proto == IPPROTO_TCP ? - TCP(ulp) : NULL)) - != NULL) { - /* - * Found dynamic entry, update stats - * and jump to the 'action' part of - * the parent rule by setting - * f, cmd, l and clearing cmdlen. - */ - IPFW_INC_DYN_COUNTER(q, pktlen); - /* XXX we would like to have f_pos - * readily accessible in the dynamic - * rule, instead of having to - * lookup q->rule. - */ - f = q->rule; - f_pos = ipfw_find_rule(chain, - f->rulenum, f->id); - cmd = ACTION_PTR(f); - l = f->cmd_len - f->act_ofs; - ipfw_dyn_unlock(q); - cmdlen = 0; - match = 1; - break; - } - /* - * Dynamic entry not found. If CHECK_STATE, - * skip to next rule, if PROBE_STATE just - * ignore and continue with next opcode. - */ - if (cmd->opcode == O_CHECK_STATE) - l = 0; /* exit inner loop */ - match = 1; - break; - - case O_ACCEPT: - retval = 0; /* accept */ - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ - break; - - case O_PIPE: - case O_QUEUE: - set_match(args, f_pos, chain); - args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1); - if (cmd->opcode == O_PIPE) - args->rule.info |= IPFW_IS_PIPE; - if (V_fw_one_pass) - args->rule.info |= IPFW_ONEPASS; - retval = IP_FW_DUMMYNET; - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ - break; - - case O_DIVERT: - case O_TEE: - if (args->eh) /* not on layer 2 */ - break; - /* otherwise this is terminal */ - l = 0; /* exit inner loop */ - done = 1; /* exit outer loop */ - retval = (cmd->opcode == O_DIVERT) ? - IP_FW_DIVERT : IP_FW_TEE; - set_match(args, f_pos, chain); - args->rule.info = IP_FW_ARG_TABLEARG(cmd->arg1); - break; - - case O_COUNT: - IPFW_INC_RULE_COUNTER(f, pktlen); - l = 0; /* exit inner loop */ - break; - - case O_SKIPTO: - IPFW_INC_RULE_COUNTER(f, pktlen); - f_pos = jump_fast(chain, f, cmd->arg1, tablearg, 0); - /* - * Skip disabled rules, and re-enter *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406071255.s57CtPWS012716>