socsvn commit: r272257 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Tue Aug 12 08:49:59 UTC 2014
Author: dpl
Date: Tue Aug 12 08:49:58 2014
New Revision: 272257
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272257
Log:
Moved all the packet matching part into a function to be used as compiled bitcode. As a side effect, we now have taken out PULLUP_TO/PULLUP_LEN out of ip_fw2.c
Modified:
soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/ip_fw_rules.h
soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc
Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/ip_fw_rules.h
==============================================================================
--- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/ip_fw_rules.h Tue Aug 12 08:41:15 2014 (r272256)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/ip_fw_rules.h Tue Aug 12 08:49:58 2014 (r272257)
@@ -13,10 +13,16 @@
#include <sys/mbuf.h>
#include <sys/kernel.h>
+#include <net/ethernet.h>
+#include <netinet/icmp6.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_fw.h>
+#include <netinet/ip_carp.h>
+#include <netinet/pim.h>
+#include <netinet/sctp.h>
#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
#include <netinet/ip6.h>
#ifdef INET6
@@ -80,6 +86,8 @@
* then it sets p to point at the offset "len" in the mbuf. WARNING: the
* pointer might become stale after other pullups (but we never use it
* this way).
+ *
+ * This is a modified version, since returns 1, insteaf of goto pullup_failed.
*/
#define PULLUP_TO(_len, p, T) PULLUP_LEN(_len, p, sizeof(T))
#define PULLUP_LEN(_len, p, T) \
@@ -88,7 +96,7 @@
if ((m)->m_len < x) { \
args->m = m = m_pullup(m, x); \
if (m == NULL) \
- goto pullup_failed; \
+ return (1); \
} \
p = (mtod(m, char *) + (_len)); \
} while (0)
@@ -96,6 +104,249 @@
/* Needed vars defined at ip_fw2.c */
VNET_DECLARE(int, V_ipfw_vnet_ready);
+
+int
+inspect_pkt(struct ip_fw_args *args, struct ip *ip, struct mbuf *m, struct in_addr *src_ip, struct in_addr *dst_ip, uint16_t *src_port, uint16_t *dst_port, uint16_t *etype, uint16_t *ext_hd, uint16_t *iplen, int *pktlen, int *is_ipv4, int *is_ipv6, u_int *hlen, uint8_t *proto, uint8_t *icmp6_type, u_short *ip6f_mf, u_short *offset, void *ulp)
+{
+ /*
+ * if we have an ether header,
+ */
+ if (args->eh)
+ *etype = ntohs(args->eh->ether_type);
+
+ /* Identify IP packets and fill up variables. */
+ if ((*pktlen) >= sizeof(struct ip6_hdr) &&
+ (args->eh == NULL || (*etype) == ETHERTYPE_IPV6) && ip->ip_v == 6) {
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
+ *is_ipv6 = 1;
+ args->f_id.addr_type = 6;
+ (*hlen) = sizeof(struct ip6_hdr);
+ *proto = ip6->ip6_nxt;
+
+ /* Search extension headers to find upper layer protocols */
+ while (ulp == NULL && (*offset) == 0) {
+ switch (*proto) {
+ case IPPROTO_ICMPV6:
+ PULLUP_TO((*hlen), ulp, struct icmp6_hdr);
+ *icmp6_type = ICMP6(ulp)->icmp6_type;
+ break;
+
+ case IPPROTO_TCP:
+ PULLUP_TO((*hlen), ulp, struct tcphdr);
+ *dst_port = TCP(ulp)->th_dport;
+ *src_port = TCP(ulp)->th_sport;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
+ break;
+
+ case IPPROTO_SCTP:
+ PULLUP_TO((*hlen), ulp, struct sctphdr);
+ *src_port = SCTP(ulp)->src_port;
+ *dst_port = SCTP(ulp)->dest_port;
+ break;
+
+ case IPPROTO_UDP:
+ PULLUP_TO((*hlen), ulp, struct udphdr);
+ *dst_port = UDP(ulp)->uh_dport;
+ *src_port = UDP(ulp)->uh_sport;
+ break;
+
+ case IPPROTO_HOPOPTS: /* RFC 2460 */
+ PULLUP_TO((*hlen), ulp, struct ip6_hbh);
+ *ext_hd |= EXT_HOPOPTS;
+ (*hlen) += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ *proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_ROUTING: /* RFC 2460 */
+ PULLUP_TO((*hlen), ulp, struct ip6_rthdr);
+ switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
+ case 0:
+ *ext_hd |= EXT_RTHDR0;
+ break;
+ case 2:
+ *ext_hd |= EXT_RTHDR2;
+ break;
+ default:
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Unknown "
+ "Routing Header type(%d)\n",
+ ((struct ip6_rthdr *)
+ ulp)->ip6r_type);
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ break;
+ }
+ *ext_hd |= EXT_ROUTING;
+ (*hlen) += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
+ *proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_FRAGMENT: /* RFC 2460 */
+ PULLUP_TO((*hlen), ulp, struct ip6_frag);
+ *ext_hd |= EXT_FRAGMENT;
+ (*hlen) += sizeof (struct ip6_frag);
+ *proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
+ *offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
+ IP6F_OFF_MASK;
+ *ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
+ IP6F_MORE_FRAG;
+ if (V_fw_permit_single_frag6 == 0 &&
+ *offset == 0 && *ip6f_mf == 0) {
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Invalid "
+ "Fragment Header\n");
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ break;
+ }
+ args->f_id.extra =
+ ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
+ ulp = NULL;
+ break;
+
+ case IPPROTO_DSTOPTS: /* RFC 2460 */
+ PULLUP_TO((*hlen), ulp, struct ip6_hbh);
+ *ext_hd |= EXT_DSTOPTS;
+ (*hlen) += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ *proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_AH: /* RFC 2402 */
+ PULLUP_TO((*hlen), ulp, struct ip6_ext);
+ *ext_hd |= EXT_AH;
+ (*hlen) += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
+ *proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_ESP: /* RFC 2406 */
+ PULLUP_TO((*hlen), ulp, uint32_t); /* SPI, Seq# */
+ /* Anything past Seq# is variable length and
+ * data past this ext. header is encrypted. */
+ *ext_hd |= EXT_ESP;
+ break;
+
+ case IPPROTO_NONE: /* RFC 2460 */
+ /*
+ * Packet ends here, and IPv6 header has
+ * already been pulled up. If ip6e_len!=0
+ * then octets must be ignored.
+ */
+ ulp = ip; /* non-NULL to get out of loop. */
+ break;
+
+ case IPPROTO_OSPFIGP:
+ /* XXX OSPF header check? */
+ PULLUP_TO((*hlen), ulp, struct ip6_ext);
+ break;
+
+ case IPPROTO_PIM:
+ /* XXX PIM header check? */
+ PULLUP_TO((*hlen), ulp, struct pim);
+ break;
+
+ case IPPROTO_CARP:
+ PULLUP_TO((*hlen), ulp, struct carp_header);
+ if (((struct carp_header *)ulp)->carp_version !=
+ CARP_VERSION)
+ return (IP_FW_DENY);
+ if (((struct carp_header *)ulp)->carp_type !=
+ CARP_ADVERTISEMENT)
+ return (IP_FW_DENY);
+ break;
+
+ case IPPROTO_IPV6: /* RFC 2893 */
+ PULLUP_TO((*hlen), ulp, struct ip6_hdr);
+ break;
+
+ case IPPROTO_IPV4: /* RFC 2893 */
+ PULLUP_TO((*hlen), ulp, struct ip);
+ break;
+
+ default:
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Unknown "
+ "Extension Header(%d), ext_hd=%x\n",
+ *proto, *ext_hd);
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ PULLUP_TO((*hlen), ulp, struct ip6_ext);
+ break;
+ } /*switch */
+ }
+ ip = mtod(m, struct ip *);
+ ip6 = (struct ip6_hdr *)ip;
+ args->f_id.src_ip6 = ip6->ip6_src;
+ args->f_id.dst_ip6 = ip6->ip6_dst;
+ args->f_id.src_ip = 0;
+ args->f_id.dst_ip = 0;
+ args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
+ } else if ((*pktlen) >= sizeof(struct ip) &&
+ (args->eh == NULL || (*etype) == ETHERTYPE_IP) && ip->ip_v == 4) {
+ *is_ipv4 = 1;
+ (*hlen) = ip->ip_hl << 2;
+ args->f_id.addr_type = 4;
+
+ /*
+ * Collect parameters into local variables for faster matching.
+ */
+ *proto = ip->ip_p;
+ *src_ip = ip->ip_src;
+ *dst_ip = ip->ip_dst;
+ *offset = ntohs(ip->ip_off) & IP_OFFMASK;
+ *iplen = ntohs(ip->ip_len);
+ *pktlen = *iplen < (*pktlen) ? *iplen : (*pktlen);
+
+ if (*offset == 0) {
+ switch (*proto) {
+ case IPPROTO_TCP:
+ PULLUP_TO((*hlen), ulp, struct tcphdr);
+ *dst_port = TCP(ulp)->th_dport;
+ *src_port = TCP(ulp)->th_sport;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
+ break;
+
+ case IPPROTO_SCTP:
+ PULLUP_TO((*hlen), ulp, struct sctphdr);
+ *src_port = SCTP(ulp)->src_port;
+ *dst_port = SCTP(ulp)->dest_port;
+ break;
+
+ case IPPROTO_UDP:
+ PULLUP_TO((*hlen), ulp, struct udphdr);
+ *dst_port = UDP(ulp)->uh_dport;
+ *src_port = UDP(ulp)->uh_sport;
+ break;
+
+ case IPPROTO_ICMP:
+ PULLUP_TO((*hlen), ulp, struct icmphdr);
+ //args->f_id.flags = ICMP(ulp)->icmp_type;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ip = mtod(m, struct ip *);
+ args->f_id.src_ip = ntohl((*src_ip).s_addr);
+ args->f_id.dst_ip = ntohl((*dst_ip).s_addr);
+ }
+
+ if (*proto) { /* we may have port numbers, store them */
+ args->f_id.proto = *proto;
+ args->f_id.src_port = *src_port = ntohs(*src_port);
+ args->f_id.dst_port = *dst_port = ntohs(*dst_port);
+ }
+
+ return (0);
+}
+
/*
* Auxiliar functions.
*/
@@ -1167,16 +1418,7 @@
static IPFW_RULES_INLINE int
rule_tcpopts(int *match, u_int hlen, void *ulp, uint8_t proto, u_short offset, ipfw_insn *cmd, struct mbuf *m, struct ip_fw_args *args)
{
- /* Modified PULLUP_TO, returns 1 if error */
- do {
- int x = (hlen) + (TCP(ulp)->th_off << 2);
- if ((m)->m_len < x) {
- args->m = m = m_pullup(m, x);
- if (m == NULL)
- return (1);
- }
- ulp = (mtod(m, char *) + (hlen));
- } while (0);
+ PULLUP_TO(hlen, ulp , (TCP(ulp)->th_off << 2));
*match = (proto == IPPROTO_TCP && offset == 0 &&
tcpopts_match(TCP(ulp), cmd));
Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc
==============================================================================
--- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Tue Aug 12 08:41:15 2014 (r272256)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Tue Aug 12 08:49:58 2014 (r272257)
@@ -86,7 +86,7 @@
Value *ext_hd; //unsigned
// This sets up some vars, at star time.
- Function *look_pkt;
+ Function *inspect_pkt;
// Auxiliary functions used by our JITed code.
Function *is_icmp_query;
@@ -240,7 +240,7 @@
// Get Function defs from bitcode.
// All of them are auxiliary functions.
- look_pkt = mod->getFunction("look_pkt");
+ inspect_pkt = mod->getFunction("inspect_pkt");
is_icmp_query = mod->getFunction("is_icmp_query");
flags_match = mod->getFunction("flags_match");
ipopts_match = mod->getFunction("ipopts_match");
@@ -296,12 +296,12 @@
return ((funcptr)NULL);
}
- // Emits all the code necessary to fill in some vars.
- // XXX Should we emit that? Or should we create a function call instead?
+ // Call the function that fills in some vars.
int
emit_lookpkt()
{
- //irb.CreateCall();
+ // If it returns zero, we have to goto pullup_failed.
+ irb.CreateCall(inspect_pkt);
return (0);
}
More information about the svn-soc-all
mailing list