Page MenuHomeFreeBSD

D39555.diff
No OneTemporary

D39555.diff

diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -759,7 +759,7 @@
Tags are "sticky", meaning once a tag is applied to a packet by a
matching rule it exists until explicit removal.
Tags are kept with the packet everywhere within the kernel, but are
-lost when packet leaves the kernel, for example, on transmitting
+lost when the packet leaves the kernel, for example, on transmitting
packet out to the network or sending packet to a
.Xr divert 4
socket.
@@ -793,6 +793,27 @@
is searched among the tags attached to this packet and,
if found, removed from it.
Other tags bound to packet, if present, are left untouched.
+.It Cm setmark Ar value | tablearg
+When a packet matches a rule with the
+.Cm setmark
+keyword, a 32-bit numeric mark is assigned to the packet.
+The mark is an extension to the tags.
+As tags, mark is "sticky" so the value is kept the same within the kernel and
+is lost when the packet leaves the kernel.
+Unlike tags, mark can be matched as a lookup table key or compared with bitwise
+mask applied against another value.
+Each packet can have only one mark, so
+.Cm setmark
+always overwrites the previous mark value.
+.Pp
+The initial mark value is 0.
+To check the current mark value, use the
+.Cm mark
+rule option.
+Mark
+.Ar value
+can be entered as decimal or hexadecimal (if prefixed by 0x), and they
+are always printed as hexadecimal.
.It Cm altq Ar queue
When a packet matches a rule with the
.Cm altq
@@ -1845,7 +1866,8 @@
One or more
of source and destination addresses and ports can be
specified.
-.It Cm lookup Bro Cm dst-ip | dst-port | dst-mac | src-ip | src-port | src-mac | uid | jail Brc Ar name
+.It Cm lookup Bro Cm dst-ip | dst-port | dst-mac | src-ip | src-port | src-mac | uid |
+.Cm jail | dscp | mark Brc Ar name
Search an entry in lookup table
.Ar name
that matches the field specified as argument.
@@ -2017,6 +2039,23 @@
Tags can be applied to the packet using
.Cm tag
rule action parameter (see it's description for details on tags).
+.It Cm mark Ar value[:bitmask] | tablearg[:bitmask]
+Matches packets whose mark is equal to
+.Ar value
+with optional
+.Ar bitmask
+applied to it.
+.Cm tablearg
+can also be used instead of an explicit
+.Ar value
+to match a value supplied by the last table lookup.
+.Pp
+Both
+.Ar value
+and
+.Ar bitmask
+can be entered as decimal or hexadecimal (if prefixed by 0x), and they
+are always printed as hexadecimal.
.It Cm tcpack Ar ack
TCP packets only.
Match if the TCP header acknowledgment number field is set to
@@ -2359,7 +2398,7 @@
.Bl -tag -width indent
.It Ar value-mask : Ar value-type Ns Op , Ns Ar value-mask
.It Ar value-type : Ar skipto | pipe | fib | nat | dscp | tag | divert |
-.Ar netgraph | limit | ipv4
+.Ar netgraph | limit | ipv4 | ipv6 | mark
.It Cm skipto
rule number to jump to.
.It Cm pipe
@@ -2382,16 +2421,19 @@
IPv4 nexthop to fwd packets to.
.It Cm ipv6
IPv6 nexthop to fwd packets to.
+.It Cm mark
+mark value to match/set.
.El
.Pp
The
.Cm tablearg
argument can be used with the following actions:
.Cm nat, pipe, queue, divert, tee, netgraph, ngtee, fwd, skipto, setfib ,
+.Cm setmark ,
action parameters:
.Cm tag, untag ,
rule options:
-.Cm limit, tagged .
+.Cm limit, tagged, mark .
.Pp
When used with the
.Cm skipto
@@ -3326,8 +3368,8 @@
.It Cm skip_global
Skip instance in case of global state lookup (see below).
.It Cm port_range Ar lower-upper
-Set the aliasing ports between the ranges given. Upper port has to be greater
-than lower.
+Set the aliasing ports between the ranges given.
+Upper port has to be greater than lower.
.El
.Pp
Some special values can be supplied instead of
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -321,6 +321,9 @@
TOK_TCPSETMSS,
+ TOK_MARK,
+ TOK_SETMARK,
+
TOK_SKIPACTION,
};
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -288,6 +288,7 @@
{ "return", TOK_RETURN },
{ "eaction", TOK_EACTION },
{ "tcp-setmss", TOK_TCPSETMSS },
+ { "setmark", TOK_SETMARK },
{ NULL, 0 } /* terminator */
};
@@ -313,6 +314,7 @@
{ "uid", LOOKUP_UID },
{ "jail", LOOKUP_JAIL },
{ "dscp", LOOKUP_DSCP },
+ { "mark", LOOKUP_MARK },
{ NULL, 0 },
};
@@ -391,6 +393,7 @@
{ "src-ip6", TOK_SRCIP6 },
{ "lookup", TOK_LOOKUP },
{ "flow", TOK_FLOW },
+ { "mark", TOK_MARK },
{ "defer-action", TOK_SKIPACTION },
{ "defer-immediate-action", TOK_SKIPACTION },
{ "//", TOK_COMMENT },
@@ -1102,6 +1105,45 @@
}
}
+/*
+ * Fill the body of the command with mark value and mask.
+ */
+static void
+fill_mark(ipfw_insn *cmd, char *av, int cblen)
+{
+ uint32_t *value, *mask;
+ char *value_str;
+
+ cmd->opcode = O_MARK;
+ cmd->len |= F_INSN_SIZE(ipfw_insn_u32) + 1;
+
+ CHECK_CMDLEN;
+
+ value = (uint32_t *)(cmd + 1);
+ mask = value + 1;
+
+ value_str = strsep(&av, ":");
+
+ if (strcmp(value_str, "tablearg") == 0) {
+ cmd->arg1 = IP_FW_TARG;
+ *value = 0;
+ } else {
+ /* This is not a tablearg */
+ cmd->arg1 |= 0x8000;
+ *value = strtoul(value_str, NULL, 0);
+ }
+ if (av)
+ *mask = strtoul(av, NULL, 0);
+ else
+ *mask = 0xFFFFFFFF;
+
+ if ((*value & *mask) != *value)
+ errx(EX_DATAERR, "Static mark value: some bits in value are"
+ " set that will be masked out by mask "
+ "(%#x & %#x) = %#x != %#x",
+ *value, *mask, (*value & *mask), *value);
+}
+
static struct _s_x icmpcodes[] = {
{ "net", ICMP_UNREACH_NET },
{ "host", ICMP_UNREACH_HOST },
@@ -1788,6 +1830,19 @@
case O_SKIP_ACTION:
bprintf(bp, " defer-immediate-action");
break;
+ case O_MARK:
+ bprintf(bp, " mark");
+ if (cmd->arg1 == IP_FW_TARG)
+ bprintf(bp, " tablearg");
+ else
+ bprintf(bp, " %#x",
+ ((const ipfw_insn_u32 *)cmd)->d[0]);
+
+ if (((const ipfw_insn_u32 *)cmd)->d[1] != 0xFFFFFFFF)
+ bprintf(bp, ":%#x",
+ ((const ipfw_insn_u32 *)cmd)->d[1]);
+ break;
+
default:
bprintf(bp, " [opcode %d len %d]", cmd->opcode,
cmd->len);
@@ -2031,6 +2086,13 @@
else
bprint_uint_arg(bp, "call ", cmd->arg1);
break;
+ case O_SETMARK:
+ if (cmd->arg1 == IP_FW_TARG) {
+ bprintf(bp, "setmark tablearg");
+ break;
+ }
+ bprintf(bp, "setmark %#x", ((const ipfw_insn_u32 *)cmd)->d[0]);
+ break;
default:
bprintf(bp, "** unrecognized action %d len %d ",
cmd->opcode, cmd->len);
@@ -2175,7 +2237,7 @@
O_CHECK_STATE, O_ACCEPT, O_COUNT, O_DENY, O_REJECT,
O_UNREACH6, O_SKIPTO, O_PIPE, O_QUEUE, O_DIVERT, O_TEE,
O_NETGRAPH, O_NGTEE, O_FORWARD_IP, O_FORWARD_IP6, O_NAT,
- O_SETFIB, O_SETDSCP, O_REASS, O_CALLRETURN,
+ O_SETFIB, O_SETDSCP, O_REASS, O_CALLRETURN, O_SETMARK,
/* keep the following opcodes at the end of the list */
O_EXTERNAL_ACTION, O_EXTERNAL_INSTANCE, O_EXTERNAL_DATA
};
@@ -4244,6 +4306,23 @@
fill_cmd(action, O_CALLRETURN, F_NOT, 0);
break;
+ case TOK_SETMARK: {
+ action->opcode = O_SETMARK;
+ action->len = F_INSN_SIZE(ipfw_insn_u32);
+ NEED1("missing mark");
+ if (strcmp(*av, "tablearg") == 0) {
+ action->arg1 = IP_FW_TARG;
+ } else {
+ ((ipfw_insn_u32 *)action)->d[0] =
+ strtoul(*av, NULL, 0);
+ /* This is not a tablearg */
+ action->arg1 |= 0x8000;
+ }
+ av++;
+ CHECK_CMDLEN;
+ break;
+ }
+
case TOK_TCPSETMSS: {
u_long mss;
uint16_t idx;
@@ -5131,6 +5210,12 @@
fill_cmd(cmd, O_SKIP_ACTION, 0, 0);
break;
+ case TOK_MARK:
+ NEED1("missing mark value:mask");
+ fill_mark(cmd, *av, cblen);
+ av++;
+ break;
+
default:
errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s);
}
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -106,6 +106,7 @@
{ "limit", IPFW_VTYPE_LIMIT },
{ "ipv4", IPFW_VTYPE_NH4 },
{ "ipv6", IPFW_VTYPE_NH6 },
+ { "mark", IPFW_VTYPE_MARK },
{ NULL, 0 }
};
@@ -916,7 +917,7 @@
memcpy(pbuf, oh, sizeof(*oh));
oh = (ipfw_obj_header *)pbuf;
- oh->opheader.version = 1;
+ oh->opheader.version = 1; /* Current version */
ctlv = (ipfw_obj_ctlv *)(oh + 1);
ctlv->count = count;
@@ -1662,6 +1663,11 @@
}
etype = "ipv6";
break;
+ case IPFW_VTYPE_MARK:
+ v->mark = strtol(n, &e, 16);
+ if (*e != '\0')
+ etype = "mark";
+ break;
}
if (etype != NULL)
@@ -1878,6 +1884,9 @@
NI_NUMERICHOST) == 0)
l = snprintf(buf, sz, "%s,", abuf);
break;
+ case IPFW_VTYPE_MARK:
+ l = snprintf(buf, sz, "%#x,", v->mark);
+ break;
}
buf += l;
@@ -2034,37 +2043,17 @@
}
-/* Copy of current kernel table_value structure */
-struct _table_value {
- uint32_t tag; /* O_TAG/O_TAGGED */
- uint32_t pipe; /* O_PIPE/O_QUEUE */
- uint16_t divert; /* O_DIVERT/O_TEE */
- uint16_t skipto; /* skipto, CALLRET */
- uint32_t netgraph; /* O_NETGRAPH/O_NGTEE */
- uint32_t fib; /* O_SETFIB */
- uint32_t nat; /* O_NAT */
- uint32_t nh4;
- uint8_t dscp;
- uint8_t spare0;
- uint16_t spare1;
- /* -- 32 bytes -- */
- struct in6_addr nh6;
- uint32_t limit; /* O_LIMIT */
- uint32_t zoneid;
- uint64_t refcnt; /* Number of references */
-};
-
static int
compare_values(const void *_a, const void *_b)
{
- const struct _table_value *a, *b;
+ const ipfw_table_value *a, *b;
- a = (const struct _table_value *)_a;
- b = (const struct _table_value *)_b;
+ a = (const ipfw_table_value *)_a;
+ b = (const ipfw_table_value *)_b;
- if (a->spare1 < b->spare1)
+ if (a->kidx < b->kidx)
return (-1);
- else if (a->spare1 > b->spare1)
+ else if (a->kidx > b->kidx)
return (1);
return (0);
@@ -2075,7 +2064,7 @@
{
char buf[128];
ipfw_obj_lheader *olh;
- struct _table_value *v;
+ ipfw_table_value *v;
uint32_t i, vmask;
int error;
@@ -2087,13 +2076,13 @@
table_print_valheader(buf, sizeof(buf), vmask);
printf("HEADER: %s\n", buf);
- v = (struct _table_value *)(olh + 1);
+ v = (ipfw_table_value *)(olh + 1);
qsort(v, olh->count, olh->objsize, compare_values);
for (i = 0; i < olh->count; i++) {
table_show_value(buf, sizeof(buf), (ipfw_table_value *)v,
vmask, 0);
- printf("[%u] refs=%lu %s\n", v->spare1, (u_long)v->refcnt, buf);
- v = (struct _table_value *)((caddr_t)v + olh->objsize);
+ printf("[%u] refs=%lu %s\n", v->kidx, (u_long)v->refcnt, buf);
+ v = (ipfw_table_value *)((caddr_t)v + olh->objsize);
}
free(olh);
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -298,6 +298,9 @@
O_MAC_SRC_LOOKUP, /* arg1=table number, u32=value */
O_MAC_DST_LOOKUP, /* arg1=table number, u32=value */
+ O_SETMARK, /* u32 = value */
+ O_MARK, /* 2 u32 = value, bitmask */
+
O_LAST_OPCODE /* not an opcode! */
};
@@ -314,6 +317,7 @@
LOOKUP_DSCP,
LOOKUP_DST_MAC,
LOOKUP_SRC_MAC,
+ LOOKUP_MARK,
};
/*
@@ -790,6 +794,7 @@
#define IPFW_VTYPE_LIMIT 0x00000100 /* limit */
#define IPFW_VTYPE_NH4 0x00000200 /* IPv4 nexthop */
#define IPFW_VTYPE_NH6 0x00000400 /* IPv6 nexthop */
+#define IPFW_VTYPE_MARK 0x00000800 /* [fw]mark */
/* MAC/InfiniBand/etc address length */
#define IPFW_MAX_L2_ADDR_LEN 20
@@ -888,6 +893,7 @@
} a;
};
+/* 64-byte structure representing multi-field table value */
typedef struct _ipfw_table_value {
uint32_t tag; /* O_TAG/O_TAGGED */
uint32_t pipe; /* O_PIPE/O_QUEUE */
@@ -899,11 +905,12 @@
uint32_t nh4;
uint8_t dscp;
uint8_t spare0;
- uint16_t spare1;
+ uint16_t kidx; /* value kernel index */
struct in6_addr nh6;
uint32_t limit; /* O_LIMIT */
uint32_t zoneid; /* scope zone id for nh6 */
- uint64_t reserved;
+ uint32_t mark; /* O_SETMARK/O_MARK */
+ uint32_t refcnt; /* XXX 64-bit in kernel */
} ipfw_table_value;
/* Table entry TLV */
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -272,13 +272,30 @@
* On entry, the structure is valid if slot>0, and refers to the starting
* rules. 'info' contains the reason for reinject, e.g. divert port,
* divert direction, and so on.
+ *
+ * Packet Mark is an analogue to ipfw tags with O(1) lookup from mbuf while
+ * regular tags require a single-linked list traversal. Mark is a 32-bit
+ * number that can be looked up in a table [with 'number' table-type], matched
+ * or compared with a number with optional mask applied before comparison.
+ * Having generic nature, Mark can be used in a variety of needs.
+ * For example, it could be used as a security group: mark will hold a
+ * security group id and represent a group of packet flows that shares same
+ * access control policy.
+ * O_MASK opcode can match mark value bitwise so one can build a hierarchical
+ * model designating different meanings for a bit range(s).
*/
struct ipfw_rule_ref {
+/* struct m_tag spans 24 bytes above this point, see mbuf_tags(9) */
+ /* spare space just to be save in case struct m_tag grows */
+/* -- 32 bytes -- */
uint32_t slot; /* slot for matching rule */
uint32_t rulenum; /* matching rule number */
uint32_t rule_id; /* matching rule id */
uint32_t chain_id; /* ruleset id */
uint32_t info; /* see below */
+ uint32_t pkt_mark; /* packet mark */
+ uint32_t spare[2];
+/* -- 64 bytes -- */
};
enum {
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -2127,6 +2127,11 @@
eh->ether_shost;
keylen = ETHER_ADDR_LEN;
break;
+ case LOOKUP_MARK:
+ key = args->rule.pkt_mark;
+ pkey = &key;
+ keylen = sizeof(key);
+ break;
}
if (keylen == 0)
break;
@@ -2773,6 +2778,19 @@
}
break;
}
+
+ case O_MARK: {
+ uint32_t mark;
+ if (cmd->arg1 == IP_FW_TARG)
+ mark = TARG_VAL(chain, tablearg, mark);
+ else
+ mark = ((ipfw_insn_u32 *)cmd)->d[0];
+ match =
+ (args->rule.pkt_mark &
+ ((ipfw_insn_u32 *)cmd)->d[1]) ==
+ (mark & ((ipfw_insn_u32 *)cmd)->d[1]);
+ break;
+ }
/*
* The second set of opcodes represents 'actions',
@@ -3276,6 +3294,18 @@
done = 1; /* exit outer loop */
break;
}
+
+ case O_SETMARK: {
+ l = 0; /* exit inner loop */
+ args->rule.pkt_mark = (
+ (cmd->arg1 == IP_FW_TARG) ?
+ TARG_VAL(chain, tablearg, mark) :
+ ((ipfw_insn_u32 *)cmd)->d[0]);
+
+ IPFW_INC_RULE_COUNTER(f, pktlen);
+ break;
+ }
+
case O_EXTERNAL_ACTION:
l = 0; /* in any case exit inner loop */
retval = ipfw_run_eaction(chain, args,
diff --git a/sys/netpfil/ipfw/ip_fw_log.c b/sys/netpfil/ipfw/ip_fw_log.c
--- a/sys/netpfil/ipfw/ip_fw_log.c
+++ b/sys/netpfil/ipfw/ip_fw_log.c
@@ -104,7 +104,7 @@
{
char *action;
int limit_reached = 0;
- char action2[92], proto[128], fragment[32];
+ char action2[92], proto[128], fragment[32], mark_str[24];
if (V_fw_verbose == 0) {
if (args->flags & IPFW_ARGS_LENMASK)
@@ -276,6 +276,14 @@
snprintf(SNPARGS(action2, 0), "Call %d",
cmd->arg1);
break;
+ case O_SETMARK:
+ if (cmd->arg1 == IP_FW_TARG)
+ snprintf(SNPARGS(action2, 0), "SetMark %#x",
+ TARG(cmd->arg1, mark));
+ else
+ snprintf(SNPARGS(action2, 0), "SetMark %#x",
+ ((ipfw_insn_u32 *)cmd)->d[0]);
+ break;
case O_EXTERNAL_ACTION:
snprintf(SNPARGS(action2, 0), "Eaction %s",
((struct named_object *)SRV_OBJECT(chain,
@@ -410,14 +418,22 @@
(ipoff & IP_MF) ? "+" : "");
}
}
+
+ /* [fw]mark */
+ if (args->rule.pkt_mark)
+ snprintf(SNPARGS(mark_str, 0), " mark:%#x",
+ args->rule.pkt_mark);
+ else
+ mark_str[0] = '\0';
+
#ifdef __FreeBSD__
- log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s %s via %s%s\n",
- f ? f->rulenum : -1, action, proto,
+ log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s%s %s via %s%s\n",
+ f ? f->rulenum : -1, action, proto, mark_str,
args->flags & IPFW_ARGS_OUT ? "out" : "in", args->ifp->if_xname,
fragment);
#else
- log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s [no if info]%s\n",
- f ? f->rulenum : -1, action, proto, fragment);
+ log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s%s [no if info]%s\n",
+ f ? f->rulenum : -1, action, proto, mark_str, fragment);
#endif
if (limit_reached)
log(LOG_SECURITY | LOG_NOTICE,
diff --git a/sys/netpfil/ipfw/ip_fw_pfil.c b/sys/netpfil/ipfw/ip_fw_pfil.c
--- a/sys/netpfil/ipfw/ip_fw_pfil.c
+++ b/sys/netpfil/ipfw/ip_fw_pfil.c
@@ -146,6 +146,7 @@
args.m = *m0;
args.ifp = ifp;
args.inp = inp;
+ args.rule.pkt_mark = 0;
ipfw = ipfw_chk(&args);
*m0 = args.m;
@@ -356,7 +357,7 @@
return (PFIL_PASS);
args.flags |= IPFW_ARGS_REF;
}
- args.m = *m0,
+ args.m = *m0;
ipfw = ipfw_chk(&args);
*m0 = args.m;
diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h
--- a/sys/netpfil/ipfw/ip_fw_private.h
+++ b/sys/netpfil/ipfw/ip_fw_private.h
@@ -330,12 +330,13 @@
uint16_t divert; /* O_DIVERT/O_TEE */
uint16_t skipto; /* skipto, CALLRET */
uint32_t netgraph; /* O_NETGRAPH/O_NGTEE */
- uint32_t fib; /* O_SETFIB */
- uint32_t nat; /* O_NAT */
+ uint16_t fib; /* O_SETFIB */
+ uint16_t nat; /* O_NAT */
+ uint32_t mark; /* O_SETMARK/O_MARK */
uint32_t nh4;
uint8_t dscp;
uint8_t spare0;
- uint16_t spare1;
+ uint16_t kidx; /* value kernel index */
/* -- 32 bytes -- */
struct in6_addr nh6;
uint32_t limit; /* O_LIMIT */
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -566,6 +566,8 @@
break;
case O_SETFIB:
case O_SETDSCP:
+ case O_SETMARK:
+ case O_MARK:
if (cmd->arg1 == IP_FW_TABLEARG)
cmd->arg1 = IP_FW_TARG;
else
@@ -650,6 +652,8 @@
break;
case O_SETFIB:
case O_SETDSCP:
+ case O_SETMARK:
+ case O_MARK:
if (cmd->arg1 == IP_FW_TARG)
cmd->arg1 = IP_FW_TABLEARG;
else
@@ -1939,6 +1943,7 @@
break;
case O_DSCP:
+ case O_MARK:
if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1)
goto bad_size;
break;
@@ -2001,6 +2006,10 @@
case O_CHECK_STATE:
ci->object_opcodes++;
goto check_size;
+ case O_SETMARK:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
+ goto bad_size;
+ goto check_action;
case O_REJECT:
/* "unreach needfrag" has variable len. */
if ((cmdlen == F_INSN_SIZE(ipfw_insn) ||
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c
--- a/sys/netpfil/ipfw/ip_fw_table.c
+++ b/sys/netpfil/ipfw/ip_fw_table.c
@@ -2760,6 +2760,7 @@
case LOOKUP_UID:
case LOOKUP_JAIL:
case LOOKUP_DSCP:
+ case LOOKUP_MARK:
*ptype = IPFW_TABLE_NUMBER;
break;
case LOOKUP_DST_MAC:
diff --git a/sys/netpfil/ipfw/ip_fw_table_value.c b/sys/netpfil/ipfw/ip_fw_table_value.c
--- a/sys/netpfil/ipfw/ip_fw_table_value.c
+++ b/sys/netpfil/ipfw/ip_fw_table_value.c
@@ -114,6 +114,7 @@
_MCPY(netgraph, IPFW_VTYPE_NETGRAPH);
_MCPY(fib, IPFW_VTYPE_FIB);
_MCPY(nat, IPFW_VTYPE_NAT);
+ _MCPY(mark, IPFW_VTYPE_MARK);
_MCPY(dscp, IPFW_VTYPE_DSCP);
_MCPY(nh4, IPFW_VTYPE_NH4);
_MCPY(nh6, IPFW_VTYPE_NH6);
@@ -615,6 +616,7 @@
v->nh4 = value; /* host format */
v->dscp = value;
v->limit = value;
+ v->mark = value;
}
/*
@@ -653,6 +655,7 @@
v.nh6 = iv->nh6;
v.limit = iv->limit;
v.zoneid = iv->zoneid;
+ v.mark = iv->mark;
memcpy(iv, &v, sizeof(ipfw_table_value));
}
@@ -679,33 +682,34 @@
iv.nh4 = v->nh4;
iv.nh6 = v->nh6;
iv.zoneid = v->zoneid;
+ iv.mark = v->mark;
memcpy(piv, &iv, sizeof(iv));
}
/*
- * Exports real value data into ipfw_table_value structure.
- * Utilizes "spare1" field to store kernel index.
+ * Exports real value data into ipfw_table_value structure including refcnt.
*/
static int
dump_tvalue(struct namedobj_instance *ni, struct named_object *no, void *arg)
{
struct vdump_args *da;
struct table_val_link *ptv;
- struct table_value *v;
+ ipfw_table_value *v;
da = (struct vdump_args *)arg;
ptv = (struct table_val_link *)no;
- v = (struct table_value *)ipfw_get_sopt_space(da->sd, sizeof(*v));
+ v = (ipfw_table_value *)ipfw_get_sopt_space(da->sd, sizeof(*v));
/* Out of memory, returning */
if (v == NULL) {
da->error = ENOMEM;
return (ENOMEM);
}
- memcpy(v, ptv->pval, sizeof(*v));
- v->spare1 = ptv->no.kidx;
+ ipfw_export_table_value_v1(ptv->pval, v);
+ v->refcnt = ptv->pval->refcnt;
+ v->kidx = ptv->no.kidx;
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 9, 4:15 PM (20 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16557578
Default Alt Text
D39555.diff (19 KB)

Event Timeline