Date: Mon, 3 Apr 2017 02:44:40 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316434 - in head: sbin/ipfw sys/netinet sys/netpfil/ipfw Message-ID: <201704030244.v332iecr029906@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Mon Apr 3 02:44:40 2017 New Revision: 316434 URL: https://svnweb.freebsd.org/changeset/base/316434 Log: Add O_EXTERNAL_DATA opcode support. This opcode can be used to attach some data to external action opcode. And unlike to O_EXTERNAL_INSTANCE opcode, this opcode does not require creating of named instance to pass configuration arguments to external action handler. The data is coming just next to O_EXTERNAL_ACTION opcode. The userlevel part currenly supports formatting for opcode with ipfw_insn size, by default it expects u16 numeric value in the arg1. Obtained from: Yandex LLC MFC after: 2 weeks Sponsored by: Yandex LLC Modified: head/sbin/ipfw/ipfw2.c head/sys/netinet/ip_fw.h head/sys/netpfil/ipfw/ip_fw_eaction.c head/sys/netpfil/ipfw/ip_fw_sockopt.c Modified: head/sbin/ipfw/ipfw2.c ============================================================================== --- head/sbin/ipfw/ipfw2.c Mon Apr 3 02:26:30 2017 (r316433) +++ head/sbin/ipfw/ipfw2.c Mon Apr 3 02:44:40 2017 (r316434) @@ -1642,6 +1642,22 @@ show_static_rule(struct cmdline_opts *co break; } + case O_EXTERNAL_DATA: { + if (has_eaction == NULL) + break; + /* + * Currently we support data formatting only for + * external data with datalen u16. For unknown data + * print its size in bytes. + */ + if (cmd->len == F_INSN_SIZE(ipfw_insn)) + bprintf(bp, " %u", cmd->arg1); + else + bprintf(bp, " %ubytes", + cmd->len * sizeof(uint32_t)); + break; + } + case O_SETDSCP: { const char *code; Modified: head/sys/netinet/ip_fw.h ============================================================================== --- head/sys/netinet/ip_fw.h Mon Apr 3 02:26:30 2017 (r316433) +++ head/sys/netinet/ip_fw.h Mon Apr 3 02:44:40 2017 (r316434) @@ -281,6 +281,7 @@ enum ipfw_opcodes { /* arguments (4 byt O_EXTERNAL_ACTION, /* arg1=id of external action handler */ O_EXTERNAL_INSTANCE, /* arg1=id of eaction handler instance */ + O_EXTERNAL_DATA, /* variable length data */ O_LAST_OPCODE /* not an opcode! */ }; Modified: head/sys/netpfil/ipfw/ip_fw_eaction.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_eaction.c Mon Apr 3 02:26:30 2017 (r316433) +++ head/sys/netpfil/ipfw/ip_fw_eaction.c Mon Apr 3 02:44:40 2017 (r316434) @@ -1,6 +1,6 @@ /*- - * Copyright (c) 2016 Yandex LLC - * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org> + * Copyright (c) 2016-2017 Yandex LLC + * Copyright (c) 2016-2017 Andrey V. Elsukov <ae@FreeBSD.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$"); * rules. * Module should implement opcode handler with type ipfw_eaction_t. * This handler will be called by ipfw_chk() function when - * O_EXTERNAL_ACTION opcode will be matched. The handler must return + * O_EXTERNAL_ACTION opcode is matched. The handler must return * value used as return value in ipfw_chk(), i.e. IP_FW_PASS, * IP_FW_DENY (see ip_fw_private.h). * Also the last argument must be set by handler. If it is zero, @@ -69,9 +69,12 @@ __FBSDID("$FreeBSD$"); * This function will return eaction_id, that can be used by module. * * It is possible to pass some additional information to external - * action handler via the O_EXTERNAL_INSTANCE opcode. This opcode - * will be next after the O_EXTERNAL_ACTION opcode. cmd->arg1 will - * contain index of named object related to instance of external action. + * action handler using O_EXTERNAL_INSTANCE and O_EXTERNAL_DATA opcodes. + * Such opcodes should be next after the O_EXTERNAL_ACTION opcode. + * For the O_EXTERNAL_INSTANCE opcode the cmd->arg1 contains index of named + * object related to an instance of external action. + * For the O_EXTERNAL_DATA opcode the cmd contains the data that can be used + * by external action handler without needing to create named instance. * * In case when eaction module uses named instances, it should register * opcode rewriting routines for O_EXTERNAL_INSTANCE opcode. The @@ -284,11 +287,13 @@ reset_eaction_obj(struct ip_fw_chain *ch /* * Since named_object related to this instance will be * also destroyed, truncate the chain of opcodes to - * remove O_EXTERNAL_INSTANCE opcode. + * remove the rest of cmd chain just after O_EXTERNAL_ACTION + * opcode. */ if (rule->act_ofs < rule->cmd_len - 1) { - EACTION_DEBUG("truncate rule %d", rule->rulenum); - rule->cmd_len--; + EACTION_DEBUG("truncate rule %d: len %u -> %u", + rule->rulenum, rule->cmd_len, rule->act_ofs + 1); + rule->cmd_len = rule->act_ofs + 1; } } IPFW_WUNLOCK(ch); Modified: head/sys/netpfil/ipfw/ip_fw_sockopt.c ============================================================================== --- head/sys/netpfil/ipfw/ip_fw_sockopt.c Mon Apr 3 02:26:30 2017 (r316433) +++ head/sys/netpfil/ipfw/ip_fw_sockopt.c Mon Apr 3 02:44:40 2017 (r316434) @@ -1736,11 +1736,16 @@ check_ipfw_rule_body(ipfw_insn *cmd, int return (EINVAL); } ci->object_opcodes++; - /* Do we have O_EXTERNAL_INSTANCE opcode? */ + /* + * Do we have O_EXTERNAL_INSTANCE or O_EXTERNAL_DATA + * opcode? + */ if (l != cmdlen) { l -= cmdlen; cmd += cmdlen; cmdlen = F_LEN(cmd); + if (cmd->opcode == O_EXTERNAL_DATA) + goto check_action; if (cmd->opcode != O_EXTERNAL_INSTANCE) { printf("ipfw: invalid opcode " "next to external action %u\n", @@ -2618,11 +2623,11 @@ unref_rule_objects(struct ip_fw_chain *c continue; no = rw->find_bykidx(ch, kidx); - KASSERT(no != NULL, ("table id %d not found", kidx)); + KASSERT(no != NULL, ("object id %d not found", kidx)); KASSERT(no->subtype == subtype, - ("wrong type %d (%d) for table id %d", + ("wrong type %d (%d) for object id %d", no->subtype, subtype, kidx)); - KASSERT(no->refcnt > 0, ("refcount for table %d is %d", + KASSERT(no->refcnt > 0, ("refcount for object %d is %d", kidx, no->refcnt)); if (no->refcnt == 1 && rw->destroy_object != NULL)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704030244.v332iecr029906>