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 <a...@freebsd.org>
+ * Copyright (c) 2016-2017 Yandex LLC
+ * Copyright (c) 2016-2017 Andrey V. Elsukov <a...@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)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to