Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109713956
D39555.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D39555.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D39555: [fw]mark implementation for ipfw
Attached
Detach File
Event Timeline
Log In to Comment